Files
rengine/shared/definitions/launch.py
T
Yogesh OjhaandClaude Sonnet 5 118728a968 feat(secrets): mine stored responses for exposed credentials
Seventh surface dimension. Passive response mining for credentials,
tokens, keys and contacts already stored in http_assets bodies and
headers — no request is ever sent, no key is tested for validity.

- shared/definitions/secrets.py: 44 detectors across cloud, code,
  payments, messaging, AI, auth, data, platform and contact groups
- shared/services/secret_mining/: detector sweep, the only writer of
  secrets/secret_sightings/secret_coverage, fingerprint + context
- stages/secret_mining/: one stage, one knob, on by default, off
  under passive intensity via touches_target=False
- shared/services/asset_query/secret_compiler.py + the SECRET_QUERY
  grammar: is:exposed / is:new / group: / secret: / state: search
- api/app/services/secret.py + api/app/api/v1/secrets.py: search,
  facets, coverage, groups, detail
- worker/app/tasks/secrets.py: backfill beat for scans mined before
  the stage existed
- Frontend: secrets table and detail sheet built to match the scans
  table (plain values, soft state badges, no explanatory copy),
  own query bar, coverage strip, quick filters
- Wired into every SURFACE_ORDER fan-out (surface scope, dashboard,
  reports, rescan, scan compare, notes, MCP)
- Wired into scan compare (SPECS/COMPARE_KEYS/WATCHED_FIELDS) and
  notes (ASSET_IDENTITY)

Values are stored and shown plain, no encryption, no masking, no
reveal endpoint, no audit trail — a stored value is already exposed
the moment the response was read.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpxhGvFNFCcEEf4gZykvka
2026-09-15 05:55:23 +05:30

35 lines
1.1 KiB
Python

from shared.enums.scan import AssetKind, Intensity, StageGroup
from shared.enums.target import TargetType
DEFAULT_LAUNCH_INTENSITY = Intensity.NORMAL.value
QUICK_SCAN_LABEL = "Quick scan"
MAX_LABEL_STAGES = 3
STAGE_GROUP_LABELS: dict[str, str] = {
StageGroup.HOSTS.value: "Hosts",
StageGroup.ADDRESSES.value: "Addresses",
StageGroup.SERVICES.value: "Services",
StageGroup.WEB.value: "Web",
StageGroup.ENDPOINTS.value: "Endpoints",
StageGroup.VULNERABILITIES.value: "Vulnerabilities",
StageGroup.ANALYSIS.value: "Analysis",
}
ASSET_KIND_LABELS: dict[str, str] = {
AssetKind.HOSTS.value: "hosts",
AssetKind.ADDRESSES.value: "addresses",
AssetKind.PORTS.value: "open ports",
AssetKind.HTTP_ASSETS.value: "HTTP assets",
AssetKind.ENDPOINTS.value: "endpoints",
AssetKind.VULNERABILITIES.value: "findings",
AssetKind.SECRETS.value: "secrets",
}
SEED_PRODUCES: dict[str, frozenset[str]] = {
TargetType.URL.value: frozenset({AssetKind.HOSTS.value}),
}
def seed_produces(target_type: str) -> frozenset[str]:
return SEED_PRODUCES.get(target_type, frozenset())