Files
rengine/shared/models/instance_settings.py
T
Yogesh OjhaandClaude Opus 5 5bf2d0395c feat(vulnerabilities): rank findings by exploitation, re-scored nightly without rescanning
Severity alone is close to useless for ordering work: roughly 60% of CVEs
score 7.0 or above. Until now EPSS and KEV came from nuclei's template
metadata, frozen at authoring time, so a finding could never learn that the
world had changed around it.

Two keyless feeds now land nightly and re-score every finding already stored:
EPSS (368k CVEs) and the CISA KEV catalog (1,695). A feed that fails to
download leaves its table untouched, so an install with no egress keeps
ranking. CISA is authoritative for is_kev on anything carrying a CVE.

exploitation.py judges each finding the way interest/ judges hosts, and the
signals that matter cross dimensions no other tool joins:

  ransom_path     a KEV ransomware CVE on a host whose ports also expose
                  a service ransomware crews reach for
  fresh_exploit   a public exploit published after the scan that found it
  untestable      no scanner template covers this CVE, so no scan can
                  clear it -- BlueKeep, EternalBlue and HTTP/2 Rapid Reset
                  all report false here
  reachable       answering directly, with no CDN or WAF in front

vulnx is an optional ceiling, never the floor: per-CVE exploits and their
links, template coverage, internet-wide population and bounty activity,
cached forever. Measured at 10 requests a minute keyless with no Retry-After,
so the client paces off the remaining header and can only ever be a
background cache-fill.

Alerting is delta-only, on the same rule as new findings: intel_signals is
upserted so created_at is when a finding first earned a signal, and repeated
refreshes alert nothing.

The nightly download is opt-out (instance_settings.threat_intel_auto_sync).
It gates the beat task and the worker warm-up only -- Refresh now always
works, so nobody is stuck with a scheduled outbound request they did not ask
for. Bounty activity renders only under CAP_HACKERONE; the gate is
presentational, so switching mode never loses data.

Every count is a promise: coverage, the query it compiles to, and the rows
its sheet opens were verified equal across all five signals.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PwxTAkPFUXPHPvdYT8Rhtm
2026-09-07 11:18:04 +05:30

87 lines
3.0 KiB
Python

import uuid
from datetime import datetime
from pydantic import BaseModel
from sqlalchemy import Column
from sqlalchemy.types import JSON
from sqlmodel import Field, SQLModel, UniqueConstraint
from shared.enums.instance import InstanceMode
from shared.utils.datetime import utc_now
class InstanceSettings(SQLModel, table=True):
__tablename__ = "instance_settings"
__table_args__ = (
UniqueConstraint("singleton_key", name="uq_instance_settings_singleton"),
)
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True, index=True)
singleton_key: str = Field(default="instance", max_length=20)
instance_name: str = Field(default="reNgine", max_length=120)
timezone: str = Field(default="UTC", max_length=64)
mode: str = Field(default=InstanceMode.BUG_BOUNTY.value)
onboarding_completed: bool = Field(default=False)
onboarding_completed_at: datetime | None = Field(default=None)
onboarding_completed_by: uuid.UUID | None = Field(default=None)
onboarding_step: int = Field(default=0)
onboarding_state: dict = Field(
default_factory=dict, sa_column=Column(JSON, nullable=False)
)
scan_history_retention_days: int = Field(default=90)
screenshot_retention_days: int = Field(default=30)
ai_enabled: bool = Field(default=False)
ai_provider: str | None = Field(default=None)
ai_model: str | None = Field(default=None)
ai_api_key_encrypted: str | None = Field(default=None)
ai_features: dict = Field(
default_factory=dict, sa_column=Column(JSON, nullable=False)
)
report_defaults: dict = Field(
default_factory=dict, sa_column=Column(JSON, nullable=False)
)
threat_intel_auto_sync: bool = Field(default=True)
mcp_enabled: bool = Field(default=False)
mcp_settings: dict = Field(
default_factory=dict, sa_column=Column(JSON, nullable=False)
)
created_at: datetime = Field(default_factory=utc_now)
updated_at: datetime = Field(default_factory=utc_now)
class InstanceSettingsUpdate(BaseModel):
instance_name: str | None = None
timezone: str | None = None
mode: str | None = None
scan_history_retention_days: int | None = None
screenshot_retention_days: int | None = None
ai_enabled: bool | None = None
ai_provider: str | None = None
ai_model: str | None = None
ai_api_key: str | None = None
ai_features: dict | None = None
class InstanceSettingsRead(BaseModel):
id: uuid.UUID
singleton_key: str
instance_name: str
timezone: str
mode: str
onboarding_completed: bool
onboarding_completed_at: datetime | None
onboarding_completed_by: uuid.UUID | None
onboarding_step: int
onboarding_state: dict
scan_history_retention_days: int
screenshot_retention_days: int
ai_enabled: bool
ai_provider: str | None
ai_model: str | None
ai_api_key_masked: str | None
ai_configured: bool
ai_features: dict
capabilities: list[str]
created_at: datetime
updated_at: datetime