Check specification

content-security-policy 1.0.0

Content-Security-Policy

Validates enforcing CSP delivery, directive syntax, resource restrictions, script execution posture, hardening directives, and reporting signals.

Assessment Suite
2026.06.10
Maturity
Established
Category
Security & Trust
Subcategory
Browser Trust

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

Resources inspected
Content-Security-Policy, Content-Security-Policy-Report-Only, script-src, object-src, base-uri

4. Scoring Semantics

Step IDTitleWeightDescription
applicabilityValidate CSP applicability0.1Confirm the response is a browser-rendered HTML document where CSP is expected.
deliveryFind enforcing CSP delivery0.15Require an enforcing Content-Security-Policy response header and record report-only, meta, and legacy signals separately.
syntaxParse CSP directives0.15Parse serialized policies, directive names, source lists, duplicate directives, unknown directives, and empty policies.
fetch-baselineEvaluate fetch baseline0.15Check default-src and explicit fetch directives for meaningful resource-loading restrictions.
script-executionEvaluate script execution0.25Evaluate effective script policy, nonce/hash strategy, strict-dynamic, broad sources, unsafe-inline, unsafe-eval, and dangerous schemes.
hardening-directivesReview hardening directives0.15Review object-src, base-uri, form-action, frame-ancestors, mixed-content controls, and Trusted Types directives.
reportingReview CSP reporting0.05Record report-to and report-uri monitoring directives without requiring reporting for baseline protection.

5. Package Documentation

Content Security Policy Check v1.0.0

Status

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-Policy carries enforcing policies.
  • Content-Security-Policy-Report-Only carries 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, and sandbox are not supported in meta CSP.
  • Obsolete legacy headers such as X-Content-Security-Policy and X-WebKit-CSP do not satisfy this check.

Important directive behavior:

  • default-src is 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 to default-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-Policy response header is present
  • the enforcing policy contains parseable directives
  • duplicate directives are absent
  • default-src is meaningful, or equivalent explicit fetch directives are present
  • script execution is constrained by script-src or an effective fallback
  • script sources avoid broad wildcard execution
  • unsafe-inline is absent, or appears only with nonce/hash controls
  • unsafe-eval is absent
  • data: and blob: are not allowed for script execution
  • object-src is restricted, preferably with object-src 'none'
  • base-uri is 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-inline appears without clear nonce/hash controls
  • unsafe-eval or wasm-unsafe-eval appears
  • script sources allow broad schemes or wildcard hosts
  • object-src is missing and default-src is not strict enough to cover object loading
  • base-uri is missing
  • form-action is 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-Policy header
  • only Content-Security-Policy-Report-Only is 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: or blob:
  • 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:, and blob: script indicators
  • object-src, base-uri, form-action, frame-ancestors, mixed-content controls, and Trusted Types directives
  • report-to and report-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 enforcing Content-Security-Policy response 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): evaluate default-src and 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): evaluate object-src, base-uri, form-action, frame-ancestors, mixed-content controls, and Trusted Types directives where relevant.
  • reporting (0.05): record report-to and report-uri monitoring 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-ancestors in 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-Policy response header delivery
  • report-only, meta, and obsolete legacy CSP signals
  • parseable directives, duplicate directives, and unknown directives
  • default-src and explicit fetch directive coverage
  • effective script execution controls
  • object-src, base-uri, form-action, frame-ancestors, mixed-content, and Trusted Types hardening signals
  • report-to and report-uri monitoring signals

Source: lib/checks/content-security-policy/versions/1.0.0/changelog.md