A fast, concurrent HTTP security header scanner that grades websites A–F and provides actionable remediation.
I'm a CS student specializing in cybersecurity, and I wanted a tool that grades sites the way Mozilla Observatory does but as a CLI I can drop into any CI/CD pipeline. The trickiest part was getting the grading boundaries and weak-value detection right — for example, HSTS without includeSubDomains is a WARN, not a PASS, because subdomains remain vulnerable to downgrade attacks. A deliberate scope limitation: the CSP check is shallow — it catches unsafe-inline, unsafe-eval, and missing default-src, but it doesn't flag wildcard sources or data: schemes. That's on the roadmap for v2.
| Header | Weight | Key checks |
|---|---|---|
| Strict-Transport-Security | 20 | Present, max-age ≥ 1 year, includeSubDomains |
| Content-Security-Policy | 20 | Present, no unsafe-inline/unsafe-eval |
| X-Frame-Options | 15 | DENY or SAMEORIGIN |
| X-Content-Type-Options | 15 | nosniff |
| Referrer-Policy | 10 | Present, not unsafe-url |
| Permissions-Policy | 10 | Present, not empty |
| Cross-Origin-Opener-Policy | 5 | Present |
| Cross-Origin-Resource-Policy | 5 | Present |
| X-XSS-Protection | 0 | Deprecated — noted but not scored |
git clone https://github.com/dilrajsooch/HTTP-Security-Header-Scanner.git
cd HTTP-Security-Header-Scanner
pip install -e ".[dev]"Scan a single site:
headscan https://example.comScan multiple sites:
headscan https://example.com https://github.com https://google.comScan from a file (one URL per line):
headscan -f urls.txtJSON output (for CI/CD pipelines):
headscan https://example.com --jsonSave JSON report to file:
headscan https://example.com --json -o report.jsonControl concurrency for large batches:
headscan -f urls.txt -c 20Set a custom request timeout (seconds):
headscan https://example.com --timeout 30Use --fail-on-grade to fail your pipeline when any scanned site falls below a grade threshold. The process exits with code 2 on grade failure (distinct from exit code 1 for scan errors).
# GitHub Actions example
- name: Check security headers
run: headscan https://your-app.com --fail-on-grade B --json -o headers.json# Fail CI if any site grades below C
headscan -f production-urls.txt --fail-on-grade C
# Strict mode — require an A
headscan https://your-app.com --fail-on-grade A| Exit code | Meaning |
|---|---|
| 0 | All scans succeeded (and met grade threshold if set) |
| 1 | One or more URLs failed to scan (network error, DNS, timeout) |
| 2 | One or more sites graded below the --fail-on-grade threshold |
| Grade | Score |
|---|---|
| A | 90–100% |
| B | 80–89% |
| C | 70–79% |
| D | 60–69% |
| F | < 60% |
pytest -v- Deeper CSP analysis — flag wildcard sources (
*),data:,blob:URIs, and report-only vs enforced mode - HEAD-request mode with GET fallback — faster scanning without downloading response bodies, with automatic retry when servers return different headers for HEAD
- Parallel scanning of redirect chains — analyze headers at each hop, not just the final destination
- Cross-validation with securityheaders.com or Mozilla Observatory results
MIT