The Scan Pipeline¶
klyrek-cli's run_scan() is the one function that ties all fourteen packages together. Here's the real sequence, in order:
def run_scan(target_url, options=None, transport=None) -> ScanResult:
scope = AuthorizationScope(authorized_hosts=[hostname, f"*.{hostname}", *options.extra_hosts])
target = Target(base_url=target_url, hosts=[hostname])
with KlyrekHTTPClient(scope, config=..., transport=transport) as client:
result = Crawler(client, max_pages=..., max_depth=...).crawl(target)
_enrich_pages(client, result, options) # tech + headers + session detection
_enrich_scripts(client, result, options) # klyrek-js: secrets + endpoints
_enrich_forms(result, options) # klyrek-auth: form classification
_enrich_api(client, result, options) # klyrek-api: spec/root/graphql discovery
_enrich_assets(client, result, options) # klyrek-assets: sensitive file probing
_enrich_discovered_endpoints(client, result, options) # tech + headers for JS/API-discovered URLs
return result
Stage by stage¶
- Crawl (
klyrek-crawler) — a breadth-first crawl within the declared scope builds the initial page graph, recordingcrawler(pages),crawler-script(<script src>references), andcrawler-form(form actions + field names) endpoints. - Enrich pages — every
crawler-sourced endpoint is re-fetched and passed throughklyrek-tech's fingerprinting,klyrek-headers's security header checks, andklyrek-auth's session-mechanism detection. - Enrich scripts — every
crawler-scriptendpoint's JS body is scanned byklyrek-jsfor hardcoded secrets and API-shaped endpoint literals, which get added to the result as newjs-endpointrecords. - Enrich forms —
klyrek-auth'sfind_auth_forms()classifies everycrawler-formendpoint as login/register/password-reset/logout based on URL and field-name heuristics. - Enrich API —
klyrek-api'sbuild_api_inventory()probes common OpenAPI/Swagger/GraphQL paths against the scan's base URL, adding any discovered routes. - Enrich assets —
klyrek-assetsprobes a curated list of commonly-exposed file paths (.env,.git/config,backup.sql, ...) against the base URL. - Enrich discovered endpoints — anything found in steps 3, 5, or 6 (
js-endpoint,api-discovery,api-spec,api-graphql) gets the same tech-fingerprint and header-check treatment as step 2. This exists specifically because a JS-only-referenced API (afetch()call with no<a>link — the common single-page-app pattern) would otherwise never get analyzed at all, despite being a real, in-scope, reachable endpoint.
The shared result object¶
Every stage writes into the same ScanResult, so you can stop after any step and inspect exactly what's been found so far — result.endpoints, result.technologies, result.findings all accumulate as the pipeline runs. klyrek-report and klyrek-monitor both operate purely on this shared object, which is what lets you render a report, snapshot a scan, or diff two scans without any of them needing to know how the result was produced.