Lint a Content-Security-Policy
Lint a Content-Security-Policy against a fixed CSP 1 to 3 ruleset: unknown and duplicate directives, weak nonces, hash lengths, risky sources and policy advice.
Working…
Questions people ask
- How should the policy be formatted?
- Exactly as it is sent: semicolon-separated directives. A pasted multi-line policy works too, because newlines are treated as plain spaces before splitting on semicolons; quote your keywords as in the header itself ('self', 'none', 'nonce-...' and so on).
- What kinds of problems does the linter find?
- Syntax errors such as duplicate directives, source-list directives with no sources, unbalanced single quotes and bad hash lengths; risky constructs such as unsafe-inline, unsafe-eval, bare wildcards, plain http: sources and data: or blob: in script destinations; and policy-level gaps such as a missing base-uri, frame-ancestors or form-action.
- A finding is not a proof, is it?
- No. One heuristic run cannot prove a policy secure or insecure. The linter reports syntax errors and known-risky constructs for the directives it knows; policies differ in context, and a clean result in the linter is not an approval from your threat model.
- Why is a directive reported as unknown?
- The fixed ruleset covers the directives CSP Levels 1 to 3 define. Newer or withdrawn experimental directives are reported as unknown so you know they are outside the checked set; the report tells you they would be ignored, not that they are forbidden.
- Does the linter visit the domains in the policy?
- Never. The tool is a pure parser: it has no network access, and source expressions such as cdn.example are read as text and never contacted. Wildcard subdomains are classed as informational, which is not a DNS test.
- What are the limits?
- One policy, either a 1 MB file or a 256 KB paste. The findings list is capped at 200 entries with totals beyond that, and source-list directives are linted to 1,000 tokens with the remainder counted. The linter never fetches anything.