mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-21 07:41:28 +02:00
The menu read as hacker cosplay rather than security software: "Worth a look" as a product feature, swords for the tool library, a sparkle for a risk surface, a crosshair for the asset list. "Worth a look" is now Exposures. Studying what the layer does settles the name: it scores an asset for what it IS — admin interface, developer tooling, remote access, non-production, legacy, no authentication, exposed content, takeover risk — and for how far it stands out from the estate. That is an exposure, the Gartner CTEM term, and it pairs with Vulnerabilities, which is what a scanner found. Bands are Critical/High/Notable, not "Look first"/"Worth a look". Only the user-visible layer is renamed. The interest/ package, the interest_signals table and InterestKind keep their names because renaming them is a migration with no user benefit. The host grammar's canonical tokens become is:exposed, exposure:<kind> and exposure_band:<band>, with the old spellings kept as aliases so no saved rule breaks — and the endpoint grammar's separate interest: (open_redirect, traversal, admin) keeps its name, so the rename removes a collision rather than creating one. Exposures also stops being a settings page. The nav item opened Rules and Dismissed while its name promised findings; it now opens the project-wide ranked list over the same QueryScope as the five dimensions, with Rules and Dismissed as tabs. Judging and rule suggestions are per-run and stay hidden there, and a project view reports stale=false so it never queues a re-label. Naming and icons elsewhere: - IPs -> IP addresses; the other four dimensions keep their names - Reconnaissance -> Discovery - the Services "Exposure" panel -> "Open services", freeing the word - swords -> library, sparkle -> scan-eye, crosshair -> target, plug-zap -> cable, network -> bot for MCP, layers -> sliders for scan contexts, and no two items in a group share a glyph Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EQgatRaA9fNsv2jXh4rZ47
57 lines
2.1 KiB
Python
57 lines
2.1 KiB
Python
"""The five result dimensions a scan produces, named as the UI names them."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from enum import StrEnum
|
|
|
|
from shared.enums.scan import AssetKind
|
|
|
|
|
|
class SurfaceDimension(StrEnum):
|
|
WEB_ASSETS = "web_assets"
|
|
ENDPOINTS = "endpoints"
|
|
SERVICES = "services"
|
|
IPS = "ips"
|
|
VULNERABILITIES = "vulnerabilities"
|
|
|
|
|
|
SURFACE_ORDER: tuple[str, ...] = tuple(d.value for d in SurfaceDimension)
|
|
|
|
SURFACE_LABELS: dict[str, str] = {
|
|
SurfaceDimension.WEB_ASSETS.value: "Web assets",
|
|
SurfaceDimension.ENDPOINTS.value: "Endpoints",
|
|
SurfaceDimension.SERVICES.value: "Services",
|
|
SurfaceDimension.IPS.value: "IP addresses",
|
|
SurfaceDimension.VULNERABILITIES.value: "Vulnerabilities",
|
|
}
|
|
|
|
SURFACE_NOUN: dict[str, tuple[str, str]] = {
|
|
SurfaceDimension.WEB_ASSETS.value: ("web asset", "web assets"),
|
|
SurfaceDimension.ENDPOINTS.value: ("endpoint", "endpoints"),
|
|
SurfaceDimension.SERVICES.value: ("service", "services"),
|
|
SurfaceDimension.IPS.value: ("address", "addresses"),
|
|
SurfaceDimension.VULNERABILITIES.value: ("finding", "findings"),
|
|
}
|
|
|
|
# a stage covers a dimension when it produces one of these kinds
|
|
SURFACE_KINDS: dict[str, frozenset[str]] = {
|
|
SurfaceDimension.WEB_ASSETS.value: frozenset(
|
|
{AssetKind.HOSTS.value, AssetKind.HTTP_ASSETS.value}
|
|
),
|
|
SurfaceDimension.ENDPOINTS.value: frozenset({AssetKind.ENDPOINTS.value}),
|
|
SurfaceDimension.SERVICES.value: frozenset({AssetKind.PORTS.value}),
|
|
SurfaceDimension.IPS.value: frozenset({AssetKind.ADDRESSES.value}),
|
|
SurfaceDimension.VULNERABILITIES.value: frozenset(
|
|
{AssetKind.VULNERABILITIES.value}
|
|
),
|
|
}
|
|
|
|
# the scans rollup columns a dimension's rows move; the live counter refreshes these
|
|
SURFACE_COUNT_COLUMNS: dict[str, tuple[str, ...]] = {
|
|
SurfaceDimension.WEB_ASSETS.value: ("subdomains_found", "http_assets_found"),
|
|
SurfaceDimension.ENDPOINTS.value: ("endpoints_found",),
|
|
SurfaceDimension.SERVICES.value: ("open_ports_found",),
|
|
SurfaceDimension.IPS.value: ("ips_found",),
|
|
SurfaceDimension.VULNERABILITIES.value: ("vulnerabilities_found",),
|
|
}
|