There’s no Python library for parsing Content Security Policy headers. I checked PyPI, I checked GitHub — nothing. Google has a CSP Evaluator web tool and an npm package, but if you want to analyze CSP programmatically in Python — for recon scripts, bug bounty automation, or CI pipelines — you’re on your own.
So I built one.
csp-toolkit is a Python library and CLI tool that parses CSP headers, runs 21 weakness checks, finds bypass vectors against a database of 79 known-exploitable domains, scores policies A+ to F, and does a lot more. The current release is v0.6.2 on PyPI (changelog).
pip install csp-toolkit
What It Does#
The core workflow is simple: give it a CSP, get back findings.
$ csp-toolkit analyze "script-src 'self' 'unsafe-inline' *.googleapis.com"
This outputs a severity-sorted table of findings, a letter grade, and a numeric score. The same thing works as a Python library:
import csp_toolkit
policy = csp_toolkit.parse("script-src 'self' 'unsafe-inline' *.googleapis.com")
findings = csp_toolkit.analyze(policy)
grade, score = csp_toolkit.score_policy(policy)
# F (35/100), 8 findings
But the analyzer is just the starting point. The tool exposes 15 CLI commands covering analysis, live fetch, bypass search, scanning, diffs, monitoring, auto-generated CSPs, violation reports, and more.
The Bypass Finder#
The most useful feature for bug bounty is the bypass finder. It cross-references whitelisted domains in a CSP against a curated database of:
- 66 JSONP domains with concrete callback URLs — Google (10+ subdomains), Facebook, Twitter, Yahoo, LinkedIn, Microsoft, GitHub, Spotify, Vimeo, Reddit, WordPress, Stripe, reCAPTCHA, and more
- 13 CDN domains with 31 script gadgets — AngularJS template injection, Vue.js template injection, Knockout.js data-bind, Lodash/Underscore template RCE, Handlebars prototype pollution, jQuery selector XSS
- 18+ arbitrary hosting domains where anyone can serve JS — raw.githubusercontent.com, codepen.io, vercel.app, netlify.app, pages.dev
$ csp-toolkit bypass "script-src 'self' *.googleapis.com cdnjs.cloudflare.com"
This outputs specific bypass vectors with concrete payloads. If a target whitelists *.googleapis.com in their script-src, the tool tells you exactly which JSONP endpoints on maps.googleapis.com, translate.googleapis.com, and accounts.google.com you can use — with ready-to-test <script src="..."> payloads.
You can also probe endpoints live with --check-live to verify they still respond.
How the Top 10 Websites Score#
I pointed csp-toolkit at the top websites to see how their CSP policies hold up. The results are… mixed.
| Site | Grade | Score | Findings | Bypasses | Notable |
|---|---|---|---|---|---|
| GitHub | A+ | 98 | 3 | 0 | Best in class. Nonce-based, strict-dynamic, all directives locked down. |
| A | 93 | 4 | 1 | Missing base-uri. | |
| Twitter/X | B | 83 | 6 | 5 | JSONP via twimg.com, CSP2 downgrade vector. |
| C | 78 | 7 | 3 | Wildcards in img/media, JSONP via platform.linkedin.com. | |
| D | 53 | 9 | 2 | Report-only (not enforced), unsafe-eval, https: scheme. | |
| YouTube | D | 53 | 9 | 2 | Same as Google — testing policy, not enforcing. |
| F | 31 | 13 | 7 | blob:, unsafe-eval, JSONP via facebook/google domains. | |
| F | 26 | 14 | 12 | 12 bypass vectors. blob:, unsafe-eval, data: in frames. | |
| Netflix | F | 18 | 11 | 2 | Report-only, unsafe-inline + unsafe-eval + https:. |
| Apple | F | 8 | 12 | 4 | unsafe-inline, unsafe-eval, blob:, data: everywhere. |
GitHub is the clear winner — nonce-based CSP with strict-dynamic, all critical directives present, zero bypass vectors in our database. Facebook is the worst, with 12 known bypass vectors including JSONP endpoints on graph.facebook.com, connect.facebook.net, and whitelisted Google domains.
Google and YouTube are interesting: they have reasonably designed policies using nonces and strict-dynamic, but they’re only deployed as Content-Security-Policy-Report-Only — meaning violations are logged but not blocked. The policy provides zero actual protection.
Recon Workflow#
For bug bounty, the typical workflow looks like this:
1. Batch scan your target list:
csp-toolkit scan -f targets.txt -o csv > results.csv
This fetches CSP from every URL, scores each one, and outputs a ranked table — weakest first. Focus on the F’s.
2. Check subdomains for variance:
csp-toolkit subdomains example.com
Tests ~35 common subdomains (www, api, staging, admin, etc.) and shows which ones have weaker CSP. A target might have a solid CSP on www.example.com but a wide-open policy on staging.example.com.
3. Deep-dive on weak targets:
csp-toolkit fetch https://weak-target.com --all
csp-toolkit bypass "their-csp-header-here" --check-live
4. Diff policies after deploys:
csp-toolkit diff https://target.com https://staging.target.com
Shows exactly what changed — added/removed directives, added/removed sources — and warns when changes weaken the policy.
5. Monitor for changes over time:
csp-toolkit monitor -f targets.txt # run via cron
csp-toolkit history https://target.com
Stores snapshots and alerts when a target weakens their CSP — a new unsafe-inline, a removed directive, a new broad wildcard.
Violation reports and stacked policies (v0.6+)#
If you collect CSP violation JSON (from a report-uri endpoint, Reporting API payloads, or browser exports), you can compare those reports to the policy you intend to enforce and get concrete fix hints.
violations groups reports by blocked URI and effective directive. With --csp or --csp-file, it suggests which source to add (or flags when the source is already allowed, including default-src fallback). In --fix-mode patch, it prints an additive patched CSP draft; --write-patch file.csp saves that draft for review before deploy.
csp-toolkit fetch https://example.com # copy the live header into policy.txt
csp-toolkit violations reports.json --csp-file policy.txt --fix-mode patch --write-patch patched.csp
From Python: parse_violations_json, suggest_violation_fixes, and build_patched_csp are available on the top-level package.
When a response sends multiple Content-Security-Policy headers, browsers enforce their intersection. effective approximates that: pass a file with one CSP value per line (at least two lines) and it intersects literal source lists per directive.
csp-toolkit effective -f stacked-csp.txt -o json
Other Features#
- Nonce reuse detection (
nonce-check) — fetches a URL multiple times to check if the CSP nonce is static. A static nonce completely defeats nonce-based protection. - Header injection testing (
header-inject) — tests CRLF injection vectors that could override the CSP header. - Report-URI analysis (
report-uri) — checks if the CSP reporting endpoint is reachable and accepts violations. - Violation reports (
violations) — summarize report JSON; optional CSP-aware suggestions and patched draft (--fix-mode patch,--write-patch). - Stacked CSP intersection (
effective) — combine multiple enforced header values into one approximate policy. - CSP generator (
generate) — outputs strict/moderate/permissive presets in header, meta tag, nginx, or Apache format. - Nuclei templates — 10 templates for scanning CSP at scale with ProjectDiscovery’s nuclei.
- Chrome extension — shows the CSP grade on every page you visit.
Install and Links#
pip install csp-toolkit
- GitHub: sampsonc/csp_toolkit
- PyPI: csp-toolkit (latest release: 0.6.2)
- Changelog: CHANGELOG.md
The tool is MIT licensed. Issues and PRs welcome.