Scanner group

Browser-side defenses

Eight scanners test the rules a browser enforces on the user's behalf: which origins may read a response, which cross-site requests the server accepts, where a redirect may land, which protective headers are set, and what the page itself ships to the client. All of them work from one rendered snapshot of the target plus a handful of header-level requests.

8 scanners8 DASTquick depthurl-only modeLow → Critical

How this group works

The ingestion phase renders the target once and keeps what it saw. Four of these scanners read only that snapshot and never touch the network. The other four send a few requests that differ from a normal one by a single header or query parameter, then read a single header or status in the reply. Every scanner has one rule and one guard.

Target app https://app.example rendered once by Playwright Snapshot (no requests) rendered HTML and forms first-party JS bundles cookies and response headers sourceMappingURL comments read by 4 scanners Header-level probes Origin: https://evil.com ?redirect=https://evil.com GET / (read headers) GET /static/app.js.map sent by 4 scanners One rule per scanner scannerevidenceseverity mixed-contenthttps page, http:// scriptMEDIUM sriCDN script, no integrity=MEDIUM client-exposureJWT role = service_roleCRITICAL csrf (passive)cookie without SameSiteMEDIUM corsACAO echoes evil.comHIGH csrf (active)forged Origin, still 2xxHIGH open-redirectLocation: https://evil.comHIGH security-headersno strict-transport-securityHIGH source-map200 and "mappings": in bodyHIGH Guards (step 4): SRI skips first-party URLs source-map needs real markers headers dedup server-wide frame-ancestors counts as XFO Result: LOW (http:// image) up to CRITICAL (service_role key) all 8 run in quick depth, url-only, no API key

1Ingestion renders the target once with Playwright and keeps everything it saw: the HTML, the first-party scripts, the cookies and response headers, and any sourceMappingURL comment. The eight scanners in this group all start from that.

2Four scanners never send a request. Mixed-content, SRI, client-exposure and the passive half of CSRF pattern-match the snapshot: an http:// script on an HTTPS page, a CDN script without integrity=, a Supabase JWT whose role claim is service_role, a cookie without SameSite.

3The other four send a few header-level requests and read one thing in the reply: CORS reads Access-Control-Allow-Origin, CSRF reads the status code behind a forged Origin, open-redirect reads Location, security-headers reads the header map, source-map fetches the guessed .map.

4Each rule carries a guard against a cheap false positive: SRI ignores first-party URLs, source-map demands "sources" or "mappings" in the body because SPA catch-alls answer 200 to anything, security-headers collapses a server-wide miss into one finding, and clickjacking accepts CSP frame-ancestors in place of X-Frame-Options.

5Findings range from LOW (an http:// image) to CRITICAL (a service_role key, or wildcard CORS with credentials). All eight run in the default quick depth and in url-only mode. Credentials are optional: they only let the probes land behind the login wall.

Scanners in this group

evil.comOrigin forgedPOST 200

CSRF

A state-changing request with a forged Origin that still gets a 2xx, cookies without SameSite, and POST forms without a token field.

DASTMedium–Highcsrf-scanner.md
Origin: https://evil.comACAO: https://evil.com

CORS

Three Origin probes per path prefix and four rules in strict order, from wildcard-with-credentials (Critical) down to a bare wildcard (Medium).

DASTMedium–Criticalcors-scanner.md
?next=evil.com302evil.com

Open redirect

Seventeen parameter names and seven paths, four payloads in order, and a Location header that must point off-site before anything is reported.

DASTMedium–Highopen-redirect-scanner.md
strict-transport-securitycontent-security-policyx-frame-optionsserver: nginx/1.19.0

Security headers

Six protective headers, two disclosure headers, the frame-ancestors alternative, a version regex for Server, and server-wide deduplication.

DASTLow–Highsecurity-headers-scanner.md
https://app.example<script src="http://cdn…"><img src="http://…">

Mixed content

An HTTPS page that loads http:// scripts, styles or frames (Medium) or images (Low). Passive, from the snapshot; nothing is fetched.

DASTLow–Mediumno md · from code
<script src="https://cdn…/x.js"integrity="…" missing

Subresource integrity

Cross-origin scripts (Medium) and stylesheets (Low) loaded without an integrity hash. First-party resources are excluded.

DASTLow–Mediumno md · from code
GET app.js.map200"mappings":

Source maps

Guessed and discovered .map URLs are fetched and confirmed by their JSON markers, so an SPA's 200-for-everything never counts. First-party is High.

DASTLow–Highno md · from code
eyJhbGciOi…role: "service_role"CRITICALprocess.env.DB_URL

Client exposure

First-party JS only: a Supabase service_role JWT (Critical), internal or staging URLs, and un-replaced process.env placeholders (Low).

DASTLow–Criticalno md · from code

At a glance

All eight are DAST scanners that run in the default quick depth and need only a target URL. None needs an API key, a binary or --depth deep. Credentials are optional everywhere: the four that send requests attach the auth headers when they exist.

ScannerWhat it looks atWhat it reportsSeverityNeeds
CSRFEvery POST/PUT/PATCH/DELETE endpoint, plus the snapshot's cookies and POST formsForged Origin accepted (2xx); cookie without SameSite or with SameSite=None; POST form with no known token fieldMedium–HighURL; credentials optional
CORSOne GET per distinct two-segment path prefix, with three Origin valuesWildcard with credentials; reflected Origin; null Origin; bare wildcardMedium–CriticalURL; credentials optional
Open redirectParameters named like a redirect target and paths such as /login or /auth/callback3xx with an off-site Location; JavaScript or meta-refresh redirect in the bodyMedium–HighURL; credentials optional
Security headersA GET to every unique URL, shortest firstHSTS, CSP, X-Content-Type-Options, Permissions-Policy, Referrer-Policy missing; no clickjacking protection; Server version; X-Powered-ByLow–HighURL; credentials optional
Mixed contentCaptured HTML and first-party JS of an HTTPS pagehttp:// script, link or iframe (Medium); http:// img (Low); at most 10 per kindLow–MediumHTTPS URL; no requests
SRICaptured HTML: <script src> and <link rel=stylesheet> on other originsExternal script without integrity (Medium); external stylesheet without integrity (Low); at most 20Low–MediumURL; no requests
Source mapsourceMappingURL hits from ingestion plus <asset>.map for every first-party JS asset, up to 40A reachable .map whose body contains "sources": or "mappings": first-party High, third-party LowLow–HighURL; credentials optional
Client exposureFirst-party JS only (vendor bundles filtered out)JWT with role service_role (Critical); internal, localhost or staging URL (Low); un-replaced process.env / import.meta.env name outside the public prefixes (Low)Low–CriticalURL; no requests

Why this class matters

Why it matters

These controls are the browser's half of the security model. The server can be perfectly authenticated and still lose: a reflected CORS origin lets evil.com read a logged-in user's API responses; a missing SameSite attribute lets evil.com submit a transfer with the victim's cookie; an open redirect turns your domain into a phishing link; a missing CSP means an injected script runs unhindered; a service_role key in the bundle bypasses Row Level Security for anyone who views source. Each of these is one header or one line of configuration, which is why they are cheap to test and cheap to fix.

Real-world breaches (from the scanner docs)

Netflix (2006): CSRF could change account email, password and DVD queue because the site lacked CSRF tokens. ING Direct (2008): CSRF initiated fund transfers from a victim's account when they visited a malicious page while logged in. Cryptocurrency exchanges (2016–2018): several reflected arbitrary Origin headers in CORS responses, letting attacker-controlled sites read authenticated responses with balances and API keys. British Airways (2018): the Magecart XSS attack was worsened by the absence of a Content Security Policy; script-src 'self' would have blocked the injected third-party script. Google (ongoing): its redirect endpoints have been repeatedly abused in phishing campaigns so links appear to originate from google.com.