Commit Graph
78 Commits
Author SHA1 Message Date
Yogesh Ojha 47d788df41 Add vuln nuclei module 2026-09-04 18:57:42 +05:30
Yogesh Ojha 628de28399 feat(ui): enhance service and port handling with new hover cards and service lookup 2026-09-04 09:07:46 +05:30
Yogesh OjhaandClaude Opus 5 b2ada19752 feat(scan): find origins reachable outside the CDN
Every HTTP service already carries five identities — TLS certificate, body
hash, favicon hash, header hash and JARM — and they were only ever used to
cluster hostnames. Pointed at ip:port instead, one index answers the question
pentesters ask first: which of these addresses answers directly as well as
behind the CDN?

A new origin_probe stage requests each address by IP with no hostname, so the
default virtual host is captured with the same fingerprinting as everything
else; screenshot moved to the level after it so both sides of the comparison
have an image. The correlation joins fingerprints across the CDN boundary and
reports the address, the hostnames it fronts for and what matched.

The noise filter is the whole trick, as it was for related domains. A
fingerprint's discriminating power falls off with its reach: a body hash on
two hosts identifies an application, a wildcard certificate on eighteen only
identifies the organisation, so weight drops with the number of hostnames
sharing it and the label says so. Error and near-empty bodies are excluded,
one weak signal is never a finding, and the sample shown as proof is the one
sharing the most identity rather than an arbitrary member of the group — which
is what makes the two screenshots line up.

Found on existing scan data with no re-scan: labs-prod-origin-<redacted-suffix>
answering on an AWS address with the same certificate, body and favicon as
eighteen CloudFront-fronted hostnames.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnC2xMMzV6WQnpDp5zcXoU
2026-09-04 06:21:16 +05:30
Yogesh OjhaandClaude Opus 5 ca150576e0 fix(scan): remove a deadlock window and stop failed facets zeroing a count
cdn_check and passive_ports run at the same level and both call
ip_inventory.ensure(), which on a domain scan is the first thing to write
ip_addresses — so both insert the same rows at the same moment. The row order
came from a UNION with no ORDER BY, so the two statements could take row locks
in different sequences and deadlock, failing a stage for no reason. Both
inventories now insert in a deterministic key order.

A failed facets request also overwrote the tab badge with 0, which reads as
"this scan found nothing" rather than "the request failed". Only a successful
response may restate the count now, in the Services and IPs tables alike.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnC2xMMzV6WQnpDp5zcXoU
2026-09-04 03:27:09 +05:30
Yogesh OjhaandClaude Opus 5 711517089a fix(scan): adversarial review of the service inventory
Three findings from reading the feature against itself.

Wrong description on 8 curated ports. describe() consulted _BY_NAME before
the port's own entry, and _BY_NAME keeps one spec per name, so port 2376
reported "Docker API without TLS, equivalent to root on the host" — the
opposite of what it is, and the kind of claim an operator acts on. The
port's own entry now wins unless a banner named something the port does not
imply, which keeps 2222/ssh resolving to SSH. Checked exhaustively: all 73
curated ports now return their own description and class.

is:new was quadratic. service_has_baseline correlated per row on target_id
alone, giving Postgres nothing selective to join on: 41.5M rows removed by
join filter on a 6,400-service scan. Whether an earlier scan exists is a
scan-level fact, so it is now a non-correlated EXISTS evaluated once as an
InitPlan, and the API's page-level check shares the same predicate instead of
carrying a second copy in raw SQL. On 24,897 subdomains x 6,440 services with
a populated baseline: is:new 5.5s -> 0.72s, findings 4.6s -> 1.7s.

The naabu replace left a hole. clear() committed, naabu then ran for minutes,
and only then did the rows come back, so a scan in progress showed an empty
port table for the length of the scan. Delete and insert now share one
transaction inside upsert().

Also removed SERVICE_CLASS_HELP, PORT_PROFILE_KEYS and is_sensitive(), which
had no consumers.

Measured and rejected: replacing the hosts CTE with per-address GIN lookups
(44.8s vs 191ms), and an ix_ports(target_id, ip, number) index (Postgres picks
a hash anti-join either way, 5.4ms with and without).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnC2xMMzV6WQnpDp5zcXoU
2026-09-04 03:23:23 +05:30
Yogesh OjhaandClaude Opus 5 ee9ac38b9a fix(ui): enterprise register for the service inventory copy
Conversational phrasing had crept into the strings this feature added.
Section labels are noun phrases again ("Description", not "What this is";
"Service classes", not "What is listening"), and the copy states the fact
rather than narrating it:

  Not confirmed          -> Unconfirmed
  Known exposure         -> External scanner
  Named                  -> Identified
  N web ports open with nothing answering -> N web ports with no HTTP response
  services are not a web server           -> services outside the web surface
  web services answer off port 80 and 443 -> web services on non-standard ports
  addresses that sit behind a CDN         -> addresses fronted by a CDN
  the packet rate, not this, is what the target feels
                         -> the packet rate governs load on the target

The query vocabulary gets the same treatment, since field, flag and example
descriptions render straight into the syntax sheet, autocomplete and the
findings dialog. Stage title "Known Exposure" is now "Passive Port Discovery",
which says what the stage does.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnC2xMMzV6WQnpDp5zcXoU
2026-09-04 03:11:22 +05:30
Yogesh OjhaandClaude Opus 5 d729471b4e feat(scan): name and describe the long tail of ports, with brand marks
An open port with no name is a dead end. The IANA Service Name and Transport
Protocol Port Number Registry (public domain, no key) fills the ~5,800 TCP
ports our curated map does not cover, committed as a generated data file
because it is small and slow-moving; scripts/fetch_port_registry.py rebuilds it.

IANA is the fallback vocabulary, never the authority. It still calls 9200
wap-wsp and 5601 esmagent while the internet runs Elasticsearch and Kibana
there, so WELL_KNOWN wins and gained ASM-framed descriptions of its own —
"Docker API without TLS, equivalent to root on the host" beats "Docker REST
API (plain text)". 80, 443, kibana, nessus, consul, kubelet and rabbitmq are
now named rather than falling through to a generic "http".

Provenance is carried, not hidden: describe() returns (text, from_registry)
and a registered name is presented as "IANA registration for port N. This scan
did not confirm it." — because IANA says port 12345 is a chat system. A name
the UI shows is always a name `service:<name>` can find, so the registry
writes through service_for_port into the stored column and a migration
backfills rows written before it existed.

Services also get an identity mark: the vendored Wappalyzer logo when the
service is a product, the class glyph when it is a protocol.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnC2xMMzV6WQnpDp5zcXoU
2026-09-04 02:59:14 +05:30
Yogesh OjhaandClaude Opus 5 117a3c33cf feat(scan): notify when a scan opens services the previous one did not
Detection without a delta is an inventory, not an ASM. Finalize now counts
the ports this scan is the first to see for its target and publishes a
notification, escalated to warning severity when any of them is an
administrative or datastore port.

Both delta notifications moved into `_notify_deltas` so finalize stays
under the statement budget.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnC2xMMzV6WQnpDp5zcXoU
2026-09-03 23:59:12 +05:30
Yogesh OjhaandClaude Opus 5 8cbb0e1f8a feat(scan): flag services that were not open at the previous scan
An ASM is a change-detection engine, so the service inventory needs a
baseline. `is:new` compares (ip, port) against earlier scans of the same
target and only fires when a baseline exists — a target's first scan
reports zero new services rather than marking everything new, the same
contract the host grammar already keeps.

Rows carry the evidence as `is_new` (one page-scoped lookup, not a
correlated subquery per row), shown as a badge in the row and the detail
sheet, with a New quick filter and two counted leads under Change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnC2xMMzV6WQnpDp5zcXoU
2026-09-03 23:56:59 +05:30
Yogesh OjhaandClaude Opus 5 2375f1f1e4 feat(scan): service-level port pipeline, Services tab and Exposure panel
The unit of exposure is now a service — (ip, port) — not a bare open port.

Pipeline (EXPANSION): L0 produce hosts, L1 cdn_check + passive_ports,
L2 port_scan, L3 http_probe, L4 screenshot/waf_detect/service_fingerprint.

- cdn_check applies to every target type and records cdn_type, so a domain
  scan finally knows which addresses are CDN-fronted. cdn/waf is an edge you
  do not own (edge ports only); cloud is your own machine (scanned in full).
- port_scan decides and records a per-address scan_policy (full/web/skip)
  honouring the scan context's excluded_ips, and offers port profiles,
  exclusions, scan type, a tarpit threshold and an address budget.
- passive_ports reads Shodan internetdb through naabu -passive: keyless,
  touches_target=False, so a passive-intensity scan still gets exposure data.
- http_probe seeds its host x port matrix from open ports and folds every
  live response back onto the port (is_http, tls, product).
- service_fingerprint names the software behind non-web ports with a pure
  Python banner prober (tools/banner/), including a SOCKS5 CONNECT so it
  honours the context proxy. naabu -sV is unimplemented.
- shared/definitions/ports.py is the one vocabulary; ip_inventory and
  port_inventory are the only writers of ip_addresses/ports.
- open_ports_found is measured from the table (DERIVED_COUNTS): four stages
  write ports, so summing stage results double-counted.
- naabu failures no longer report zero open ports as success.

Surfaces: a Services tab (SERVICE_QUERY grammar, 16 fields, 18 counted
leads, 9 group dimensions, detail sheet) built on the shared results shell,
and an outlier-first Exposure panel on the Overview. Every count is a
promise — leads, groups and panel pivots were verified to equal the row
count they land on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BnC2xMMzV6WQnpDp5zcXoU
2026-09-03 23:50:17 +05:30
Yogesh Ojha c12b3cd09d scan history overview tab rewrite
- Deleted `tech-stack-card.svelte` and `related-domains-card.svelte` as they are no longer needed.
- Consolidated scan overview components by integrating functionality into `scan-overview.svelte`, including the addition of `HeroPanel`, `AttentionPanel`, and `PosturePanel`.
- Removed `ScanActivityTimeline` and `ScanCommandLog` from the scan detail view, simplifying the UI.
- Updated scan insights handling to improve loading states and error management.
- Adjusted scan progress messages for clarity.
- Added `single_source` field to `SubdomainInsights` model to track source count.
2026-09-03 22:13:31 +05:30
Yogesh Ojha bc10415319 add ip-> asn, ip->cc, and global geo distribution map 2026-09-03 16:31:43 +05:30
Yogesh Ojha 5ac452fddc change ip tab datatable to match with web assets 2026-09-03 14:48:46 +05:30
Yogesh Ojha 3d251fe617 add related domains feature 2026-09-03 13:39:57 +05:30
Yogesh Ojha a17253db1d add row grouping 2026-09-03 12:46:27 +05:30
Yogesh Ojha dc53e2c5a0 add intelligence layer 2026-09-03 12:14:20 +05:30
Yogesh Ojha efe5414552 add AST search 2026-09-03 10:25:57 +05:30
Yogesh Ojha 784b3dfd26 feat: enhance scan insights and progress tracking
- Added `newOnly` filter to `WebAssetQuery` and updated related functions.
- Introduced `FilterChip` interface for better query chip management.
- Implemented `activitySummary` function to summarize scan activity results.
- Enhanced `stageRows` function to include detailed activity states and summaries.
- Updated `SubdomainInsights` and `IpGroupRead` models to include new fields for better data representation.
- Added `SENSITIVE_PORTS` definition for sensitive port tracking.
- Improved scan page UI with new tab definitions and enhanced user interactions.
- Implemented history loading for scans to track previous results.
- Added functionality to cancel ongoing scans with user confirmation.
2026-09-03 06:43:16 +05:30
Yogesh Ojha 68bbc2b83c feat: implement batch scan creation and related UI updates 2026-09-02 20:17:19 +05:30
Yogesh Ojha f98a78a0be add crtname 2026-09-02 18:55:47 +05:30
Yogesh Ojha 1498812593 feat: enhance engine management UI and backend
- Updated the engine management UI in `+page.svelte` to improve user experience with new controls for filtering stages, toggling side panels, and managing YAML configurations.
- Introduced new components such as `EngineSummaryBar` and `Resizable` for better layout handling.
- Added clipboard functionality for copying YAML configurations and formatting options.
- Enhanced the backend models in `scan_engine.py` to include a new `PreviewResolved` class for better handling of scan context and parameters.
- Updated presets in `presets.py` to clarify descriptions and improve user understanding of stage settings.
2026-09-02 18:03:52 +05:30
Yogesh Ojha 62ebc54bd1 refactor: remove scan insights component and related state management
- Deleted the `scan-insights.svelte` component as it was no longer needed.
- Removed associated state management for scan changes and change window in the scans store.
- Updated the `scan-list-item.svelte` to include progress indicators for live scans.
- Introduced a new `scan-status-tabs.svelte` component for better status management.
- Enhanced the chart tooltip to support footer rendering.
- Updated utility functions for scan progress and status to accommodate new features.
- Modified the scan model to include a new field for counting new subdomains.
- Adjusted the main scans page layout to integrate the new activity chart and status tabs.
2026-09-02 16:40:26 +05:30
Yogesh Ojha c9ba856ea7 imorove app sidebar 2026-09-02 13:04:50 +05:30
Yogesh Ojha a5e6c0ac0d feat: add target enrichment, vhost discovery, and WAF detection stages
- Implemented TargetEnrichmentStage for enriching targets with DNS, WHOIS, and BGP context.
- Added VhostStage for virtual host discovery using host-header fuzzing.
- Introduced WafDetectStage for fingerprinting web application firewalls.
- Created configuration files for each new stage with relevant parameters.
- Updated Dockerfile to copy stages instead of engines.
- Enhanced existing tools and services for better integration with new stages.
- Refactored task management in Celery to accommodate new stages and improve error handling.
2026-09-02 10:18:03 +05:30
Yogesh Ojha 1b83165e0d feat: add scan insights and correlation utilities
- Introduced new utilities for scan insights in `scan-insights.ts`, including functions for certificate state, days until expiry, and query compilation.
- Added interfaces for web asset queries, subdomain filters, and insights structures.
- Enhanced `scan-status.ts` with new constants for pagination and search debounce.
- Updated the scan results page to utilize the new insights and remove unused subdomain and asset APIs.
- Modified the `HttpAsset` model to include raw request/response data and body previews.
- Created new models for scan correlation and insights, including surface stats and attention items.
- Implemented streaming JSON parsing in the HTTPX client for memory efficiency.
- Enhanced the executor to support streaming JSON output from subprocesses.
2026-06-26 16:25:30 +05:30
Yogesh Ojha d7ed513d6a feat(scans): correlation-heavy per-scan results page
Rebuild the scan detail view into a tabbed results page: Overview
(tech/status/web-server distributions, TLS health, top networks and
services), Web assets (rich httpx table with screenshots, status,
tech, CDN/WAF/TLS-expired badges + a full per-asset detail drawer),
Subdomains (denormalized HTTP summary), Infrastructure (IP-centric
cards correlating open ports and the hosts resolving to each IP), and
Pipeline. Assets correlate by value within the scan (subdomain.name /
http_asset.host / ip), so one IP card surfaces every co-located host.

API: add per-scan http-assets, ports and ips list+summary endpoints
plus services mirroring the subdomains pattern, and serve screenshots
through an authenticated /media/screenshot route; mount scan_media
into the api container so it can read worker-written captures.

Fix two serializers that silently dropped fields: ScanRead omitted
http_assets_found (scan detail and list 500'd), and the subdomain
serializer never emitted the denormalized HTTP summary it stores.

Drop leftover docstrings and banner comments from the httpx client,
parser and field-map.
2026-06-26 16:17:53 +05:30
Yogesh Ojha fc55b48fcb feat(scans): capture full httpx field set + denormalize onto subdomain
httpx is a goldmine and we were dropping most of it. Now:

- tools/runner/fieldmap.py: a declarative field map (single source of truth) —
  adding/renaming a tool's output field is a one-line edit, reusable per tool
- httpx parser rewritten as a HTTPX_FIELDS map; captures jarm (was bugged),
  cpe (CVE mapping), response_time, words/lines, body+header hashes, all A/AAAA
  IPs, http2/pipeline, cdn_type, and a far richer TLS block (cipher, issuer_org,
  serial, fingerprint, not_before, expired-derivation)
- HttpAsset gains ~21 columns for all of it
- the primary web service summary (status/title/webserver/response_time/
  content_length/tech/cdn/screenshot) is denormalized onto the Subdomain row so
  the subdomain table renders 2.x-style without joins; HttpAsset keeps full
  per-port detail
2026-06-26 16:17:53 +05:30
Yogesh Ojha f49ff0ff82 fix(scans): http asset correlation — probed host + resolved IP
HttpAsset.ip was storing httpx's request host (the hostname), not the
resolved IP, which broke the http-asset <-> IpAddress/Port value-join. Now:

- host = the probed host (from httpx `input`) -> exact match to Subdomain.name
- ip   = the resolved IP (host_ip / A record) -> exact match to Port / IpAddress
- final_url = where a followed redirect landed, kept separate from the probed
  url so the correlation key never drifts

Adds http_assets.final_url.
2026-06-26 16:17:52 +05:30
Yogesh Ojha 81fa9e899b feat(scans): expansion phase — host discovery, vhost, screenshots, waf
Rounds out expansion (host discovery, virtual hosts, screenshots, WAF):

- host_discovery: naabu liveness sweep marks IpAddress.is_alive for
  ip_range/asn; port_scan then deep-scans only live hosts
- vhost: ffuf Host-header bruteforce (domain, opt-in) -> vhost-only
  Subdomains that http_probe then picks up
- screenshot: httpx headless chromium -> HttpAsset.screenshot_path under
  a scan_media volume
- waf_detect: wafw00f fingerprints WAFs -> HttpAsset.waf

All config-driven (ExpansionConfig) with proxy / user-agent / headers +
per-tool custom args threaded through. Adds ffuf, chromium and wafw00f to
the worker image and a scan_media volume.
2026-06-26 16:17:52 +05:30
Yogesh Ojha 42a9aa8d96 feat(scans): expansion phase — cdn check, port scan, http probe
The host:port -> live HTTP asset convergence. After discovery, a scan now
runs expansion:

- port_scan: naabu (cdn-gated, well-known service names) -> Port
- cdn_check: cdncheck flags CDN/WAF/cloud IPs (ip family)
- http_probe: httpx probes the host:port matrix; one pass enriches each
  service with status/title/tech/server/TLS/cdn/jarm/favicon/hash ->
  HttpAsset, with asn backfilled from the resolved IP

httpx -tls-grab carries cert data inline (no separate tlsx pass); nmap is
dropped — naabu for ports, httpx for HTTP service id.

Also: every engine moved to its own folder; net_options() threads
proxy/headers/user-agent into every tool; rengine-tools no longer installs
top-level modules that shadowed libs (httpx); tool binaries resolve from the
go bin ahead of venv console scripts. New Port + HttpAsset models + migration
and the http_assets headline rollup.
2026-06-26 16:17:52 +05:30
Yogesh Ojha 621d1b207c feat(scans): discovery phase for all target types
Every scan now runs a discovery phase, gated per seed type:

- seed_resolution: expand ip / cidr / asn seeds into IpAddress assets
  (stdlib ipaddress, even-stride sampling + rfc1918 skip on big ranges)
- reverse_dns: dnsx -ptr over discovered IPs
- ip_enrichment: asn / org / country from cached bgp + whois
- target_enrichment: consolidate cached whois/dns/bgp, refresh on miss/stale

The engine framework grows a phase axis (discovery/expansion/depth) and
per-stage applies_to gating so a stage skips cleanly when it doesn't apply
to the seed; subdomain discovery is retagged as expansion. Adds the
IpAddress model + migration.
2026-06-25 13:56:07 +05:30
Yogesh Ojha c58aca0b1d fix(targets,scans): cascade target delete + checkbox click + scan bulk actions
- Target delete failed when scan data existed: scans.target_id and
  activity_logs.target_id FKs had no ON DELETE rule. Add ondelete CASCADE
  (scans) / SET NULL (activity_logs) to the models + a migration that
  alters the existing constraints. Deleting a target now cascades its
  scans (and their subdomains/activities/commands) and nulls audit-log refs.
- Targets list: clicking the row checkbox bubbled to the row and navigated
  to the target summary. Wrap the checkbox in a stopProp container.
- Scan history: add per-row + select-all checkboxes and a bulk action bar
  (cancel running / delete selected) mirroring the targets pattern, backed
  by scansStore.removeMany/cancelMany.
2026-06-24 08:22:11 +05:30
Yogesh Ojha 1945242c1b feat: implement scan scheduling functionality
- Added new types and interfaces for scan scheduling in the frontend.
- Created a new Svelte page for managing scheduled scans, including listing, creating, editing, and deleting schedules.
- Implemented backend models and services for scan schedules, including handling different schedule types (one-off, interval, daily, cron).
- Introduced a Celery task to manage the execution of scheduled scans based on their defined timing.
- Enhanced notification system to include alerts for newly discovered subdomains during scans.
- Added utility functions for handling time zones and scheduling logic.
2026-06-24 08:10:21 +05:30
Yogesh Ojha 2faf1dddaf feat: Implement scan orchestrator with event publishing and tracking
- Add aggregate functions for scan status and counts in orchestrator.
- Create ScanEventPublisher for emitting scan-related events.
- Introduce ScanActivityService for managing scan activities.
- Implement ScanCommandRecorder for logging command executions.
- Develop canvas building and finalization logic for scan tasks.
- Refactor scan task to utilize orchestrator functions for running stages and finalizing scans.
- Enhance scan notification system to dispatch relevant events.
- Integrate command recording into CLI tool execution for better tracking.
2026-06-23 20:07:46 +05:30
Yogesh Ojha 01cbbb282a feat(scans): server-side scan history with ASM insights, grouping & export
Rework the scan history page into a world-class ASM view:

- Server-side table matching the Targets design: pagination, search,
  multi-select status/engine/context filters, time range, sort, active-filter
  chips, and CSV/JSON export (lean server-side /scans/export).
- "What changed" insights: net-new-subdomains hero with 6h/12h/24h/7d/30d
  windows, KPI strip (total / in-progress / success rate / last scan), and a
  stacked-area scan-activity chart (official shadcn-svelte/layerchart pattern).
- Group-by-target view: collapsible per-target runs, subdomain trend
  sparkline, and a stale-target badge.
- Per-row signals: first-scan badge (suppresses misleading baseline "new"),
  +new / -gone subdomain deltas, drop-anomaly, no-results, failure-reason
  (from scan.error), and auth-used chips.
- Backend: Page[ScanRead] list, /scans/changes, /scans/targets, /scans/export;
  ScanStats engine/context facets + daily status breakdown; per-scan
  first-seen/new/gone deltas; honest-viz (never sums per-scan snapshots).
- Indexes for the default sorted view and subdomain first-seen deltas.
- Fix target summary "Added <date> by <user>" spacing, drop the redundant
  project label, and remove the redundant /scans page header.
2026-06-22 21:39:12 +05:30
Yogesh Ojha 203024bad1 - scan engine addition but is quite basic one for now
- Updated the default route for automation to redirect to engines instead of scans.
- Removed the scans page and replaced it with a new scans overview page that lists scan history for projects.
- Introduced a detailed scan view page to display individual scan results and subdomain discoveries.
- Added new enums for scan statuses and subdomain sources to improve code clarity and maintainability.
- Implemented a new scan task in Celery to handle scan execution and logging.
- Enhanced the database models for scans and subdomains to support new features and improve data integrity.
- Updated the worker Dockerfile to include necessary scanning tools and dependencies.
- Added utility functions for domain matching and pattern compilation to streamline scan operations.
2026-06-22 15:08:58 +05:30
Yogesh Ojha 69239333bc Refactor validation and DNS tools, implementation of onboarding wizard
- Added `clean_name` function to `validation.py` for name validation with max length.
- Simplified docstrings in `dnsx` client, parser, and service files for clarity.
- Enhanced error handling in `ViewDNSService` to prevent disabling keys on rate limits.
- Improved WHOIS service to handle concurrent inserts gracefully with integrity checks.
- Updated `Settings` class in worker config to inherit from `BaseAppSettings`.
- Added new dependencies in `pyproject.toml` for `apprise` and `cryptography`.
2026-06-21 21:56:20 +05:30
Yogesh OjhaandClaude Opus 4.8 73f460999f feat(automation): scan engines, scan contexts, and engine×context launch
Scan Engine — SvelteFlow capability-flow builder (Discovery→Expansion→Depth, 14 capabilities, data-lineage edges, neutral phase bands, Recon Data terminal), Canvas/YAML dual view, CRUD + duplicate + YAML import/export; backend SQLModel + service + /engines API + migration.

Scan Context — runtime auth/scope/rate profiles (6 auth types resolving to headers server-side; secrets plaintext-at-rest but masked in every read), exclusions/inclusions, per-tool + global rate overrides, thread/timeout multipliers, protocol/redirects; full-page shadcn form + list; CRUD + duplicate; merge-ready. Baseline-compare/new-assets deferred (422).

Launch — merge_engine_context() resolves engine×context per Section 7 (headers union/context-wins, rate ceiling applied after per-tool replace, threads/timeouts ×multiplier, exclusions additive, tool-enable engine-only) into a secret-safe ResolvedScanConfig; /scans/preview dry-run + /scans launch creating a pending Scan record (engine/context name snapshots, execution_config persisted); /automation/scans page + launch modal + execution preview. Worker dispatch stubbed.

Security/QA (multi-agent adversarial review): no secret value in any API body (preview/create/list/read mask ALL header values unconditionally); same-project scoping (404 cross-project); CRLF/control-char rejection on auth + headers + scope lists; rate/thread/timeout clamps; list size caps; ScanCreate extra=forbid; engine deletion preserves scan history (no FK on scans.engine_id). Official shadcn components throughout; monochrome.

Migrations: add_scan_engines → add_scan_contexts → add_scans → drop_scan_engine_fk (applied, JSONB configs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 19:57:04 +05:30
Yogesh Ojha 48b16be96f style(correlation): terse comments
Collapse descriptive docstrings/comment blocks in the correlation engine
to single-line notes.
2026-05-31 08:03:20 +05:30
Yogesh Ojha 4bd86e79c7 Reduce correlation false positives and bound correlation queries
WHOIS/DNS correlation was grouping unrelated targets on low-signal keys.
Add centralized privacy-redaction and shared-infrastructure detection,
drop country from auto-correlation, and bound every correlation query.

Backend:
- shared/utils/privacy.py: detect privacy-proxy/redacted registrant names
  and emails (Withheld for Privacy, Domains By Proxy, WhoisGuard, GDPR
  masked, etc.) so they never become correlation keys
- shared/utils/infra.py: detect shared/managed DNS (Cloudflare, Route 53,
  GoDaddy, ...) so targets are not linked merely by DNS provider
- wire redaction into WHOIS entity extraction; guard correlation queries
  defensively so legacy redacted rows do not correlate
- drop country from get_correlations_for_target (links whole regions)
- filter shared nameservers out of WHOIS nameserver correlation
- bound all WHOIS/DNS correlation queries (limit + distinct)
- exclude CDN-fronted IPs and shared nameservers from DNS correlation
- normalize country code casing at storage to fix missed matches
- return accurate cache-hit provenance from WhoisService.lookup
- reuse service finders from correlation API endpoints (DRY)

Frontend:
- remove country as a correlation type across types, API client, and the
  related/lookup/overview WHOIS components (still shown as a record field)
2026-05-31 07:18:40 +05:30
Yogesh Ojha c6c5c61389 Refactor project and tag management, enhance error handling, and improve UI components
- Updated project slug generation to ensure uniqueness by checking active projects.
- Modified project retrieval functions to only fetch active projects.
- Introduced unique slug generation for tags associated with specific projects.
- Enhanced user authentication flow with improved error handling and session management.
- Added session expiration handling in the API client and SSE client for better user experience.
- Improved UI components for better accessibility and user feedback, including copy buttons and activity drawers.
- Refactored notification handling to ensure proper session management and state reset on logout.
- Removed unused enrichment components to streamline the codebase.
- Updated notification model to simplify JSONB handling and ensure proper expiration logic.
2026-05-23 14:33:19 +05:30
Yogesh Ojha fca02d813a refactor logger, add shared sse 2026-02-25 07:14:16 +05:30
Yogesh Ojha 668ec7d21d add SSE module 2026-02-24 13:16:55 +05:30
Yogesh Ojha 4be6739c74 add logs 2026-02-21 21:52:20 +05:30
Yogesh Ojha 4be9190868 add migration script for foreign key updates 2026-02-21 21:37:43 +05:30
Yogesh Ojha c9f56819a9 add activity stream, fix fks on delete cascade 2026-02-21 21:26:41 +05:30
Yogesh Ojha 08965b98ca add activity log model, service, and enums for structured logging 2026-02-21 18:23:50 +05:30
Yogesh Ojha a9cda464d1 add endpoints for target level details 2026-02-11 11:43:55 +05:30
Yogesh Ojha 8529ff0982 add dnsx and add executor for common tool execution 2026-02-10 22:26:55 +05:30
Yogesh Ojha 5754ae9343 refactor to use common enum for tasks 2026-02-10 21:21:29 +05:30