1. Abstract
Constrain browser resource loading and script execution with an enforcing Content-Security-Policy header.
Content Security Policy reduces the impact of injection bugs by limiting where scripts, styles, frames, forms, and other browser resources can load or execute.
2. Classification
- Check ID
- content-security-policy
- Check version
- 1.0.0
- Package path
- lib/checks/content-security-policy/versions/1.0.0
- Category
- Security & Trust
- Subcategory
- Security & Trust
- Check group
- Browser Trust
- Check group ID
- browser-trust
- Maturity
- Established
- Scope
- page
- Check weight
- 1
3. Input And Output Contracts
- Input
- [email protected]
- Output
- [email protected]
- Resources inspected
- Content-Security-Policy, Content-Security-Policy-Report-Only, script-src, object-src, base-uri
4. Scoring Semantics
| Step ID | Title | Weight | Description |
|---|---|---|---|
applicability | Validate CSP applicability | 0.1 | Confirm the response is a browser-rendered HTML document where CSP is expected. |
delivery | Find enforcing CSP delivery | 0.15 | Require an enforcing Content-Security-Policy response header and record report-only, meta, and legacy signals separately. |
syntax | Parse CSP directives | 0.15 | Parse serialized policies, directive names, source lists, duplicate directives, unknown directives, and empty policies. |
fetch-baseline | Evaluate fetch baseline | 0.15 | Check default-src and explicit fetch directives for meaningful resource-loading restrictions. |
script-execution | Evaluate script execution | 0.25 | Evaluate effective script policy, nonce/hash strategy, strict-dynamic, broad sources, unsafe-inline, unsafe-eval, and dangerous schemes. |
hardening-directives | Review hardening directives | 0.15 | Review object-src, base-uri, form-action, frame-ancestors, mixed-content controls, and Trusted Types directives. |
reporting | Review CSP reporting | 0.05 | Record report-to and report-uri monitoring directives without requiring reporting for baseline protection. |
5. Package Documentation
Content Security Policy Check v1.0.0
Status
- Version:
1.0.0 - Check identifier:
content-security-policy - Input contract:
[email protected] - Output contract:
[email protected] - Scope: page
Abstract
This check validates Content Security Policy on the scanned HTML page. It checks whether the page has an enforcing Content-Security-Policy response header, whether the policy can be parsed into directives, whether resource loading has a meaningful baseline, whether script execution is constrained, and whether important hardening and reporting directives are present.
Report-only CSP, meta-delivered CSP, and obsolete legacy CSP headers are recorded as evidence, but they do not replace an enforcing Content-Security-Policy response header.
Motivation
CSP is a browser defense-in-depth control. A strong policy reduces the impact of injection bugs by limiting where scripts, styles, frames, forms, and other resources can load or execute.
CSP does not prove an application is free of XSS. It complements output encoding, sanitization, dependency review, Trusted Types, and application security testing.
Normative Model
W3C Content Security Policy Level 3 defines CSP syntax, delivery, parsing, directive processing, and enforcement behavior.
A CSP is a serialized policy made of semicolon-separated directives. Directive names are case-insensitive. Duplicate directives in the same policy are ignored after the first occurrence. Unknown directives do not invalidate the whole policy.
Important delivery behavior:
Content-Security-Policycarries enforcing policies.Content-Security-Policy-Report-Onlycarries monitoring policies and is not enforced.- HTML
meta http-equiv="Content-Security-Policy"can deliver an enforcing policy after parsing, but it does not support the full CSP feature set. report-uri,frame-ancestors, andsandboxare not supported in meta CSP.- Obsolete legacy headers such as
X-Content-Security-PolicyandX-WebKit-CSPdo not satisfy this check.
Important directive behavior:
default-srcis a fallback for many fetch directives, but it is not a complete policy by itself.frame-ancestors,base-uri,form-action,sandbox, and reporting directives do not fall back todefault-src.- Multiple enforced policies are cumulative.
Applicability
The check applies to the scanned page response and expects browser-rendered HTML.
Non-HTML assets such as images, fonts, scripts, CSS files, binary downloads, JSON API responses, and plain-text endpoints fail this check when scanned as the primary page response.
Error pages and authentication challenges are evaluated with caution because they may not represent the site's browser application.
CSP can be processed on HTTP responses, but CSP does not replace HTTPS or HSTS.
Pass Criteria
The check passes baseline CSP validation when:
- the response is applicable HTML
- an enforcing
Content-Security-Policyresponse header is present - the enforcing policy contains parseable directives
- duplicate directives are absent
default-srcis meaningful, or equivalent explicit fetch directives are present- script execution is constrained by
script-srcor an effective fallback - script sources avoid broad wildcard execution
unsafe-inlineis absent, or appears only with nonce/hash controlsunsafe-evalis absentdata:andblob:are not allowed for script executionobject-srcis restricted, preferably withobject-src 'none'base-uriis present
Strong posture evidence includes nonce- or hash-based scripts, strict-dynamic, object-src 'none', base-uri 'none', route-appropriate form-action, route-appropriate frame-ancestors, mixed-content upgrade controls, Trusted Types directives, and CSP reporting.
Warning Criteria
Warnings include:
- the response is an error page or otherwise may not represent the main browser application
- meta CSP is present alongside an enforcing response header but has weaker or divergent coverage
- report-only CSP is present alongside a weaker enforcing policy
- duplicate directives are present but the first effective directive is still restrictive
- unknown directives are present
- script policy relies mainly on host allowlists rather than nonce/hash controls
unsafe-inlineappears without clear nonce/hash controlsunsafe-evalorwasm-unsafe-evalappears- script sources allow broad schemes or wildcard hosts
object-srcis missing anddefault-srcis not strict enough to cover object loadingbase-uriis missingform-actionis missing on pages with forms- CSP reporting directives are missing
Failure Criteria
Failures include:
- scanned response is not browser-rendered HTML
- applicable HTML page has no enforcing
Content-Security-Policyheader - only
Content-Security-Policy-Report-Onlyis present - only meta CSP is present
- only obsolete legacy CSP headers are present
- the enforcing policy contains no parseable directives
- malformed directives prevent meaningful policy evaluation
- no meaningful fetch baseline is present
default-src *is the only baseline resource policy- script execution is effectively unrestricted
- script policy allows dangerous script schemes such as
data:orblob: object-src *or broad object loading is explicitly allowed- duplicate directives cause browsers to ignore an intended restrictive later directive while an earlier directive remains weak
Evidence Model
The check emits step-level evidence for:
- final URL, status, content type, and HTML applicability
- enforcing CSP header presence
- report-only CSP header presence
- meta CSP presence
- obsolete legacy CSP headers
- summarized CSP header values
- parsed directive names
- duplicate directives
- unknown directives
- malformed directives
- effective fetch baseline
- effective script directive and source list
- nonce, hash,
strict-dynamic,unsafe-inline,unsafe-eval, wildcard, broad scheme,data:, andblob:script indicators object-src,base-uri,form-action,frame-ancestors, mixed-content controls, and Trusted Types directivesreport-toandreport-uri
Evidence must not include cookies, authorization headers, complete response header dumps, complete HTML, CSP violation report bodies containing sensitive URLs, request credentials, or unrelated sensitive values.
Validation/Scoring Steps
applicability(0.10): classify whether the response is browser-rendered HTML.delivery(0.15): require an enforcingContent-Security-Policyresponse header and record report-only, meta, and legacy signals.syntax(0.15): parse directives, values, duplicate directives, unknown directives, and empty policies.fetch-baseline(0.15): evaluatedefault-srcand explicit fetch directives.script-execution(0.25): evaluate effective script policy, nonce/hash strategy,strict-dynamic, broad sources,unsafe-inline,unsafe-eval, and dangerous schemes.hardening-directives(0.15): evaluateobject-src,base-uri,form-action,frame-ancestors, mixed-content controls, and Trusted Types directives where relevant.reporting(0.05): recordreport-toandreport-urimonitoring directives.
Standard Behavior
If an applicable HTML page lacks an enforcing CSP header, the result fails.
If a page has only report-only CSP, the result fails because report-only policies are not enforced.
If a page has an enforcing header plus report-only header, the enforcing policy determines pass, warning, or failure. The report-only policy is recorded as rollout evidence.
If a page has only meta CSP, the result fails because meta CSP lacks full feature support and applies only after parsing.
If a policy is syntactically valid but weak, the result warns or fails based on severity. Weak script execution controls are more severe than missing reporting.
Non-Standard And Real-World Behavior
Many production CSPs start in report-only mode to collect breakage reports before enforcement. That is useful rollout practice, but it is not protection until an enforcing policy ships.
Host allowlist CSPs are common and can be operationally useful, but modern security guidance favors nonce- or hash-based strict CSP because host allowlists are difficult to maintain and often bypassable.
Some applications temporarily require unsafe-eval, WebAssembly exceptions, or third-party script allowances. This check surfaces those exceptions as warnings or failures based on their effect on script execution.
frame-ancestors overlaps with a dedicated frame-protection check. This check records it as CSP hardening evidence without making it the only determinant of CSP success.
Non-Goals And Limitations
This check does not:
- prove the application is free of XSS
- replace output encoding, sanitization, Trusted Types adoption, dependency review, or application security testing
- execute attack payloads
- crawl every route
- prove nonce randomness from a single response
- prove that every script tag has the correct nonce
- prove that external script hashes match Subresource Integrity
- validate reporting endpoint availability
- treat CSP as a replacement for HTTPS, HSTS, CORS, CORP, COEP, COOP, Referrer-Policy, or X-Content-Type-Options
- require
frame-ancestorsin every CSP - require reporting for baseline protection
References
Source: lib/checks/content-security-policy/versions/1.0.0/docs.md
6. Version Changelog
content-security-policy v1.0.0 Changelog
Initial release of the Content Security Policy check.
This version evaluates:
- enforcing
Content-Security-Policyresponse header delivery - report-only, meta, and obsolete legacy CSP signals
- parseable directives, duplicate directives, and unknown directives
default-srcand explicit fetch directive coverage- effective script execution controls
object-src,base-uri,form-action,frame-ancestors, mixed-content, and Trusted Types hardening signalsreport-toandreport-urimonitoring signals
Source: lib/checks/content-security-policy/versions/1.0.0/changelog.md