Attack surface and exposure
Four pages about what an application gives away before anyone exploits it. Discovery builds the endpoint inventory every dynamic scanner works from; the three scanners here then ask one cheap question each, a known request or a known file, and decide on a string match in what comes back.
How this group works
No payload crafting, no two-account comparison, no timing oracle. Each scanner sends one well-known request (or reads one well-known file), then looks for a fixed string in the response. The inventory from discovery tells the dynamic scanners where to send it; the repository tells the static one what to read.
1Everything starts from the target URL. Playwright renders the page and keeps the HTML and every JavaScript file it pulled in. A repository is optional and only the static scanner uses it.
2Endpoint discovery turns bundles, a served spec, HTML forms and a short list of probed paths into the inventory. The scanners in this group take the inventory as given; the HTTP probe also derives the base URL (scheme plus host) from its first entry.
3HTTP probe. Known paths are fetched on the base URL. GET /.env that returns 200, a non-HTML content type and a KEY=VALUE line is reported as an exposed sensitive file at High. An SPA shell that merely contains an "=" is ignored. Nothing is exploited.
4GraphQL. Only endpoints whose path contains /graphql, /api/graphql or /gql are touched. An introspection query that comes back 2xx with __schema, __type or "types" in the body means the whole schema is public.
5OpenAPI (SAST). Any .yaml, .yml or .json file carrying an openapi: or swagger: marker is a spec. A spec with no securitySchemes or no top-level security: line describes an API that is public by default.
6The three share one shape: a cheap probe, a string match, a finding whose confidence is fixed per check rather than measured. That is why they run early, run at quick depth, and need no credentials. The pages below show each scanner's full check list and the guards that keep the string match honest.
Scanners in this group
Endpoint discovery
How the inventory every DAST scanner uses is built: bundles and lazy chunks, served specs, forms, probed paths, the authenticated crawl, and ranking per attack dimension.
HTTP probe
Five checks in cost order: verbose errors, exposed .git and .env, TRACE and CONNECT, a forged Host header, CRLF in query parameters. Also the scanner that lost four findings to a 901 s hard cancel.
GraphQL
Three probes on any /graphql endpoint: an introspection query, a query nested ten levels deep, and a two-query batch. What the body must contain for each to count.
OpenAPI spec
Six regex checks over spec files in the repo: no global security, http:// servers, Basic auth, API keys in the query string, security: [] overrides, sensitive paths with no global scheme.
At a glance
| Scanner | What it looks at | What it reports | Severity | Needs |
|---|---|---|---|---|
| Endpoint discovery | Rendered HTML, every JS bundle and lazy chunk, 13 well-known spec paths per API base, forms and query links, probed API bases | Not findings: the categorised, ranked endpoint inventory the DAST scanners consume | n/a | Target URL. Credentials add the authenticated crawl; --probe-writes adds derived POST/PUT endpoints |
| HTTP probe | Four error-trigger paths and eight sensitive paths on the base URL, then OPTIONS, TRACE, forged Host and CRLF query payloads against ranked endpoints | Verbose error page, exposed .git/HEAD or .env, directory listing, TRACE or CONNECT enabled, Host header reflected, CRLF header injection | Medium to High | Target URL only. Quick depth. 900 s timeout, stops itself at 85 % of it |
| GraphQL | Inventory entries whose path contains /graphql, /api/graphql or /gql | Introspection enabled, no query depth limit, batch queries accepted | Low to Medium | Target URL only. Quick depth. 600 s timeout. Nothing runs if no path matches |
| OpenAPI spec | .yaml, .yml, .json files in the indexed repo that contain an openapi: or swagger: marker | No global security scheme, http:// server URL, Basic auth, API key in query, security: [] override, sensitive path without global security | Medium to High | Repository only. No LLM, no binary |
The HTTP probe and GraphQL scanners are auth-aware: when a login session exists from the authenticated crawl, its headers ride along on every request so protected endpoints are probed too. Neither requires one.
Why this class matters
These findings are reconnaissance, and reconnaissance is where every attack starts. An exposed .env hands over database credentials; an exposed .git lets the source be reconstructed; a stack trace names the framework, file paths and query structure; a GraphQL schema or a Swagger document is a complete map of the API with the auth requirements of every route. Individually each looks low-risk. Chained, they decide which endpoint an attacker goes after first and with what payload.
GitLab, 2019: GraphQL introspection was enabled by default, and researchers used it to enumerate private project information and user data. GitLab then restricted introspection in production. Exposed .env files, .git directories and Swagger documents at /api-docs or /swagger.json are among the most common bug bounty findings; automated scanners probe the internet for these paths continuously, and thousands of production sites have leaked database credentials and API keys this way.