Open Source · Auditable · Forensic
Scan Methodology
WebGuard performs 20 automated security checks on every scan — no tiers, no paywalls. Every check is mapped to a published standard, every rule is deterministic and reproducible, and every finding can be traced back to a specific test ID, ASVS control, and source document. This page is the forensic reference.
··· Total Security Scans Completed and counting...
Critical
···
0–10
Vulnerable
···
11–49
Attention
···
50–79
Good
···
80–99
Hardened
···
100
Standards & Frameworks
OWASP WSTG
The OWASP Web Security Testing Guide v4.2 is the primary framework. Every check maps to a WSTG test case identifier (e.g. WSTG-CRYP-01).
owasp.org ↗OWASP ASVS
The Application Security Verification Standard v4.0.3 defines minimum baseline controls. Every check maps to an ASVS Level 1 control — the lowest bar any public site should meet, and the only level verifiable by automated external scanning.
owasp.org ↗CWE
The Common Weakness Enumeration (MITRE) classifies the type of software weakness underlying each finding.
cwe.mitre.org ↗OWASP Secure Headers
The OWASP Secure Headers Project (SHP) defines recommended values for all HTTP security response headers. Baseline for all Layer 3 header checks.
owasp.org ↗RFC Standards
Specific RFC documents define the normative requirements for TLS (RFC 8446), HSTS (RFC 6797), Cookies (RFC 6265), JWT (RFC 7519), and HTTP Methods (RFC 9110).
rfc-editor.org ↗Scan Structure — 4 Layers · 20 Checks
Layers run sequentially. A critical failure in Layer 1 or Layer 2 stops the scan immediately and sets the score to 0 — no further checks run. This is by design: there is no point analysing headers when the site transmits data in cleartext or exposes credentials in source.
Prerequisite
Encryption & connectivity fundamentals. Fail = scan stops, score 0.
2 checks · WSTG-CRYP · ASVS Level 1: 9.1.1, 9.2.1
L1-01 HTTPS Active
Site must be served over HTTPS. Checks that the submitted URL and all redirects land on https://. Plain HTTP means all traffic — including passwords — is transmitted unencrypted to any network observer.
WSTG-CRYP-01
ASVS 9.1.1 L1RFC 8446
L1-02 SSL Certificate
Attempts TLS handshake with certificate validation. Fails on expired, self-signed, hostname-mismatch, or invalid chain certificates. An invalid certificate leaves users open to man-in-the-middle interception.
WSTG-CRYP-01
ASVS 9.2.1 L1RFC 8446 §4.4.2
Instant Fail
Critical data exposure detectable in the main HTTP response. Fail = scan stops, score 0.
7 checks · WSTG-ATHN, CRYP, CONF · ASVS Level 1: 2.10.1, 9.1.1, 14.4.1, 6.2.1, 7.4.1, 4.1.1, 3.5.3
L2-01 Exposed API Keys
Regex scans page source for live credential patterns: Stripe live/test keys, AWS access keys (AKIA…), GitHub tokens (ghp_…), Google API keys (AIza…), Slack tokens (xox…), Twilio, SendGrid. Any match means live credentials are visible to anyone who views source.
WSTG-ATHN-02
ASVS 2.10.1 L1L2-02 HTTP Form Submission
Checks whether any HTML <form> element's action attribute points to an http:// URL. Form data — including passwords — submitted over HTTP is transmitted in cleartext.
WSTG-CRYP-03
ASVS 9.1.1 L1L2-03 Directory Listing
Detects server-generated directory indexes by searching for "Index of /", "Parent Directory</a>", "directory listing for", "<title>index of" in the response body. These strings are exclusive to server-generated directory listings — not navigation links.
WSTG-CONF-05
ASVS 14.4.1 L1L2-04 Sensitive Data Exposure
Regex scans the response body for: SSN patterns (\d{3}-\d{2}-\d{4}), credit card numbers (Visa, Mastercard, Amex formats), PEM private key headers (-----BEGIN PRIVATE KEY-----), and plaintext password values in JSON responses.
WSTG-CRYP-04
ASVS 6.2.1 L1L2-05 Debug / Error Exposure
Detects: active stack traces (Python Traceback, Java at …, Node.js Error), SQL error messages, debug panels (Xdebug, Django debug mode, Laravel Debugbar, Whoops!), and presence of X-Debug-Token or X-Debug-Token-Link headers.
WSTG-CONF-08
ASVS 7.4.1 L1L2-06 Admin Page Exposure
Probes 20 paths in parallel across four categories — Generic: /admin, /administrator, /manager, /manage, /backend, /console, /panel, /controlpanel, /cp, /system — WordPress: /wp-admin, /wp-login.php, /admin.php — DB tools: /phpmyadmin, /adminer — CMS/AI-app patterns: /cms, /superadmin, /portal, /moderator, /staff. HTTP 200 = instant fail — unauthenticated admin access is exploit-ready. HTTP 3xx redirects, 401, and 403 are treated as pass (auth is working). SPA detection: if all 200 responses share the same <title> as the homepage, the site uses client-side routing and is not flagged.
WSTG-CONF-05
ASVS 4.1.1 L1L2-07 JWT Algorithm None
Detects JWT tokens where the header declares alg: none — a condition that instructs the server to skip signature verification entirely. Any token can be forged and accepted as valid without a secret or private key. Authentication is fully broken. Basis: RFC 7519 §6.
WSTG-ATHN-03
ASVS 3.5.3 L1RFC 7519 §6
Passive Header Analysis
Reads HTTP response headers from the main page. No additional requests. Scored normally: fail −10, warning −5.
8 checks · WSTG-CONF, INFO, SESS, ATHN · ASVS Level 1: 14.4.x, 9.1.2, 14.3.3, 3.4.1, 3.5.3 — L3-08 is body-only warning; alg:none is in Layer 2
L3-01 Content Security Policy
Warning: header absent; or present but script-src (or effective default-src) contains 'unsafe-inline', 'unsafe-eval', or wildcard *. 'unsafe-inline' in style-src alone is not flagged — CSS injection is lower severity and commonly required by CSS frameworks (Tailwind, etc.). Pass: CSP present with no unsafe script directives.
WSTG-CONF-02
ASVS 14.4.3 L1OWASP SHP
L3-02 X-Frame-Options
Warning: X-Frame-Options header absent AND no frame-ancestors CSP directive. Pass: DENY, SAMEORIGIN, or a frame-ancestors CSP directive is present.
WSTG-CONF-02
ASVS 14.4.2 L1OWASP SHP
L3-03 HSTS
Warning: Strict-Transport-Security header absent; or present but max-age < 31536000 (1 year). Only evaluated on HTTPS sites — on HTTP sites the result is "N/A: requires HTTPS first".
WSTG-CONF-02
ASVS 9.1.2 L1RFC 6797
L3-04 Server Information Disclosure
Warning: Server header contains a version string in x.y format or more specific (e.g. nginx/1.24, Apache/2.4.58); or any X-Powered-By header is present. Generic server names without a version (e.g. cloudflare, nginx) are not flagged — they reveal the software family but not an exploitable version. X-Powered-By is always flagged regardless of content.
WSTG-INFO-02
ASVS 14.3.3 L1L3-05 X-Content-Type-Options
Warning: X-Content-Type-Options: nosniff absent. Without it, some browsers MIME-sniff responses and may execute uploaded files (e.g. images) as scripts.
WSTG-CONF-02
ASVS 14.4.4 L1OWASP SHP
L3-06 Referrer Policy
Warning: Referrer-Policy header absent; or set to unsafe-url or no-referrer-when-downgrade. Safe values: no-referrer, same-origin, strict-origin, strict-origin-when-cross-origin. Basis: W3C Referrer Policy specification.
WSTG-CONF-02
ASVS 14.4.6 L1W3C Referrer Policy
L3-07 Cookie Security
Warning: a session-relevant cookie (name matches session/auth/token patterns, or has no Expires/Max-Age) lacks one or more of: HttpOnly (prevents JS access), Secure (HTTPS only), SameSite (CSRF mitigation). Non-session cookies (analytics, preferences, A/B flags) are not evaluated. Pass + advisory note: all three flags present but cookie names do not use __Host- or __Secure- prefixes — these enforce additional browser-level constraints (__Host-: requires Secure + Path=/ + no Domain attribute; __Secure-: requires Secure flag) and are a defense-in-depth recommendation per ASVS 3.4.2 L2. Basis: RFC 6265 §4.1.3.
WSTG-SESS-02
ASVS 3.4.1 L1RFC 6265
L3-08 JWT Body Exposure
Warning: JWT token (eyJ…) found in response body. Exposed tokens may contain decodable user claims and indicate that sensitive session data is transmitted in a readable format. This check does not evaluate the algorithm — see L2-07 JWT Algorithm None for the critical instant-fail variant.
WSTG-ATHN-03
ASVS 3.5.3 L1RFC 7519
Active Probes
Sends additional targeted requests. Scored normally: fail −10, warning −5.
3 checks · WSTG-CONF, SESS · ASVS Level 1: 14.5.x, 4.2.2 — Admin moved to Layer 2
L4-01 CORS Configuration
Sends request with Origin: https://evil.example.com.
Fail: server reflects the arbitrary origin AND Access-Control-Allow-Credentials: true — enables authenticated cross-site requests (auth bypass).
Warning: server reflects the arbitrary origin without credentials — any site can read public responses; restrict if auth is involved.
Pass: Access-Control-Allow-Origin: * without credentials — acceptable for fully public APIs and CDNs. Basis: WHATWG Fetch Standard §3.2.5.
WSTG-CONF-07
ASVS 14.5.3 L1WHATWG Fetch §3.2.5
L4-02 Dangerous HTTP Methods
Sends OPTIONS request and reads Allow header. All findings are warnings — no instant-fail state.
Warning (TRACE): TRACE active — no legitimate production use; exploitable via Cross-Site Tracing (XST) to steal cookies/auth headers via JavaScript. Disable immediately.
Warning (PUT/DELETE/PATCH): elevated methods active on root URL — ensure these are restricted to authenticated endpoints. Basis: RFC 9110 §9.3.8.
WSTG-CONF-06
ASVS 14.5.1 L1RFC 9110 §9.3.8
L4-03 CSRF Protection
Warning: <form> elements with a state-changing method (POST, PUT, DELETE, PATCH) found, but no CSRF token field detected. GET forms and forms with no method attribute are not flagged — GET requests are not CSRF-relevant per RFC 7231. Token field names checked: _token, csrf, csrftoken, xsrf, authenticity_token, antiforgery, _csrf_token. SameSite=Strict/Lax cookies are also accepted as a valid CSRF mitigation. Basis: OWASP CSRF Prevention Cheat Sheet.
WSTG-SESS-05
ASVS 4.2.2 L1OWASP CSRF CS
WSTG Test Coverage — Complete Forensic Reference (Patch 01)
Every finding in a WebGuard report can be traced back to a specific internal ID, WSTG test case, ASVS control, and source document. FAIL-GATE checks stop the scan on failure; SCORED checks contribute to the risk total.
| ID | Test Name | Layer | WSTG ID | ASVS Control | Type |
|---|---|---|---|---|---|
| L1-01 | HTTPS Active | Prerequisite | WSTG-CRYP-01 | 9.1.1 L1 | FAIL-GATE |
| L1-02 | SSL Certificate | Prerequisite | WSTG-CRYP-01 | 9.2.1 L1 | FAIL-GATE |
| L2-01 | Exposed API Keys | Instant Fail | WSTG-ATHN-02 | 2.10.1 L1 | FAIL-GATE |
| L2-02 | HTTP Form Submission | Instant Fail | WSTG-CRYP-03 | 9.1.1 L1 | FAIL-GATE |
| L2-03 | Directory Listing | Instant Fail | WSTG-CONF-05 | 14.4.1 L1 | FAIL-GATE |
| L2-04 | Sensitive Data Exposure | Instant Fail | WSTG-CRYP-04 | 6.2.1 L1 | FAIL-GATE |
| L2-05 | Debug / Error Exposure | Instant Fail | WSTG-CONF-08 | 7.4.1 L1 | FAIL-GATE |
| L2-06 | Admin Page Exposure | Instant Fail | WSTG-CONF-05 | 4.1.1 L1 | FAIL-GATE |
| L2-07 | JWT Algorithm None | Instant Fail | WSTG-ATHN-03 | 3.5.3 L1 | FAIL-GATE |
| L3-01 | Content Security Policy | Passive Headers | WSTG-CONF-02 | 14.4.3 L1 | SCORED |
| L3-02 | X-Frame-Options | Passive Headers | WSTG-CONF-02 | 14.4.2 L1 | SCORED |
| L3-03 | HSTS | Passive Headers | WSTG-CONF-02 | 9.1.2 L1 | SCORED |
| L3-04 | Server Information Disclosure | Passive Headers | WSTG-INFO-02 | 14.3.3 L1 | SCORED |
| L3-05 | X-Content-Type-Options | Passive Headers | WSTG-CONF-02 | 14.4.4 L1 | SCORED |
| L3-06 | Referrer Policy | Passive Headers | WSTG-CONF-02 | 14.4.6 L1 | SCORED |
| L3-07 | Cookie Security | Passive Headers | WSTG-SESS-02 | 3.4.1 L1 | SCORED |
| L3-08 | JWT Body Exposure | Passive Headers | WSTG-ATHN-03 | 3.5.3 L1 | SCORED |
| L4-01 | CORS Configuration | Active Probes | WSTG-CONF-07 | 14.5.3 L1 | SCORED |
| L4-02 | Dangerous HTTP Methods | Active Probes | WSTG-CONF-06 | 14.5.1 L1 | SCORED |
| L4-03 | CSRF Protection | Active Probes | WSTG-SESS-05 | 4.2.2 L1 | SCORED |
Scoring
Formula
If any Layer 1 or Layer 2 check returns fail, the Security Score is immediately set to 0. Scan stops. No further calculation.
If all Layer 1 and Layer 2 checks pass, the score is calculated from Layer 3 and Layer 4 results using weighted normalized scoring:
// each check has its own weight (1–10)
raw_risk = Σ weight(check) for each fail/warning
max_possible = 57 // sum of all check max weights
risk_score = round((raw_risk / 57) × 90)
Security Score = 100 − risk_score
All L3+L4 fail/warn → risk_score 90 → score 10. No issues → score 100. Instant fail → score 0.
| Check | Warn | Fail |
|---|---|---|
| Content Security Policy | 8 | — |
| Cookie Security | 7 | — |
| HSTS | 6 | — |
| X-Frame-Options | 5 | — |
| CSRF Protection | 5 | — |
| Dangerous HTTP Methods | 5 | — |
| JWT Body Exposure | 4 | — |
| CORS Configuration | 4 | 10 |
| X-Content-Type-Options | 3 | — |
| Referrer Policy | 2 | — |
| Server Information | 2 | — |
| Admin Page Exposure | — | L2 instant-fail |
Result Definitions
No evidence of the vulnerability detected. Does not guarantee the issue is absent — it was not detectable through this scan's passive/limited-active approach.
A security best practice is not followed. Risk is real but not an immediate critical exposure. Remediation recommended.
Confirmed security issue detected. In Layer 1/2: halts scan, score = 0. In Layer 3/4: contributes the check's fail weight (see table) to normalized risk.
ASVS Level 1 Priority
Every check in WebGuard maps to an OWASP ASVS Level 1 control — the minimum security baseline for any publicly accessible web application. ASVS Level 1 is specifically designed for automated, unauthenticated external verification, which is precisely the scope of this tool. Level 2 and Level 3 controls require authenticated sessions or manual review and are outside this tool's scope. ASVS controls are not weighted differently in the scoring formula, but they represent the highest-priority items to fix.
OWASP ASVS v4.0.3 ↗Limitations
WebGuard performs unauthenticated, external, passive-first scanning. It does not simulate a logged-in attacker, does not test internal APIs behind authentication, and does not perform fuzzing or exploit attempts.
A passing score indicates that no issues were detectable from a public, unauthenticated vantage point at the time of the scan. It does not indicate the application is free of vulnerabilities. A full penetration test by a qualified security professional is always recommended for production systems handling sensitive data.
SSRF is intentionally excluded. Cloud metadata endpoint strings (AWS 169.254.169.254, GCP metadata.google.internal, etc.) appear legitimately in documentation pages, API reference responses, and example code — making any pattern-based detection non-deterministic with an unacceptably high false positive rate. SSRF assessment requires manual testing. This exclusion is a deliberate forensic decision: all findings produced by WebGuard must be reproducible and attributable to a specific rule.
Platform constraints. WebGuard runs on Cloudflare Workers with per-request limits: CPU budget, memory, and a bounded number of subrequests. The tool is scoped to the main HTTP response and a small number of targeted probe requests — not aggressive crawling or full-site enumeration. This is a deliberate design boundary that keeps the tool fast, free, and focused on what matters most for a baseline check.
Scope and positioning. WebGuard is a baseline security verification tool. It answers one specific question before you go live: does your site meet the ASVS Level 1 minimum bar? It is not a replacement for a penetration test, a DAST scanner, or a compliance audit.
Contact
Wasian
Builder of WebGuard. Questions about scan methodology, false positives, or feedback on the tool — reach out.