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. It’s on PyPI now.
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 has 12 CLI commands covering the full CSP security workflow.
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.
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. - 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
The tool is MIT licensed. Issues and PRs welcome.