CSP evaluator

Paste a Content-Security-Policy, as a header value, a whole header line, a Report-Only header, a meta element or several at once, and read it the way CSP Level 3 reads it: each directive named and explained, each source expression classified by the grammar (keyword, nonce, hash, scheme, host and its wildcards), the effective source list per destination through the fallback chain, and a graded list of findings, each quoting the specification: 'unsafe-inline' and 'unsafe-eval', wildcard, data: and http: sources, missing object-src, base-uri and frame-ancestors, short nonces, 'strict-dynamic' without a nonce, keywords without quotes, missing semicolons, duplicate, unknown and obsolete directives, directives ignored in meta or in Report-Only, and whether the policy meets the specification's own Strict CSP. Decode and grade only, offline: nothing is fetched.

Security & WAF
Try

weak At least one high finding: the policy can be bypassed or does not do what it says. Read as a header value.

Inline script is allowed ('unsafe-inline' is not overridden). eval() is allowed; WebAssembly compilation is allowed. No nonce, no hash for script.

Findings: 3 high, 3 medium, 3 low, one note, nothing marked good.

5 directives

  1. default-srcCSP3fetch directive

    The fallback for every fetch directive that is not set: "when default-src is set, every fetch directive that isn't explicitly set will fall back to the value default-src specifies." There is no inheritance: a directive that is set replaces it entirely (6.1.3).

    'self' self
  2. script-srcCSP3fetch directive

    Restricts the locations from which scripts may be executed: script requests, inline script blocks, inline event handlers (through script-src-attr's fallback), eval() and its kin (gated on 'unsafe-eval'), WebAssembly compilation (gated on 'wasm-unsafe-eval'), and worker scripts through worker-src's fallback (6.1.10).

    'self' self'unsafe-inline' keyword'unsafe-eval' keywordhttps://cdn.example.com hostdata: scheme
    • 'unsafe-inline': allows every inline script block, inline event handler, javascript: URL or inline style of the directive's type, unless a nonce or hash (or, for script, 'strict-dynamic') in the same list overrides it (6.7.3.2).
    • 'unsafe-eval': allows eval(), Function(), setTimeout and setInterval with a string, and WebAssembly compilation; a global page flag read from script-src or default-src (6.1.10).
    • https://cdn.example.com: a host-source: scheme https, host cdn.example.com, port the scheme's default, path any. A host without a scheme matches the page's scheme and its secure upgrade (6.7.2.8).
    • data:: a scheme-source: any URL whose scheme is data, on any host (6.7.2.8).
  3. img-srcCSP3fetch directive

    Restricts the URLs from which images may be loaded (6.1.6).

    * hostdata: scheme
    • *: a host-source: scheme any (the page's own, or its secure upgrade), host * (a wildcard: it matches that host's subdomains, and their subdomains), port the scheme's default, path any. A host without a scheme matches the page's scheme and its secure upgrade (6.7.2.8).
    • data:: a scheme-source: any URL whose scheme is data, on any host (6.7.2.8).
  4. style-srcCSP3fetch directive

    Restricts the locations from which style may be applied: stylesheet requests (link, @import, the Link header), inline style blocks and style attributes (6.1.13).

    'self' self'unsafe-inline' keyword
    • 'unsafe-inline': allows every inline script block, inline event handler, javascript: URL or inline style of the directive's type, unless a nonce or hash (or, for script, 'strict-dynamic') in the same list overrides it (6.7.3.2).
  5. font-srcCSP3fetch directive

    Restricts the URLs from which fonts may be loaded (6.1.4).

    https://fonts.gstatic.com host
    • https://fonts.gstatic.com: a host-source: scheme https, host fonts.gstatic.com, port the scheme's default, path any. A host without a scheme matches the page's scheme and its secure upgrade (6.7.2.8).

The effective policy

What each destination is actually governed by, after the fallback list of 6.8.3 (script-src-elem falls back to script-src, then default-src; worker-src to child-src, script-src, default-src; frame-src to child-src, default-src; the others to default-src; base-uri, form-action and frame-ancestors never fall back).

destinationgoverned bysources in force
script-src-elem script elements and requestsscript-src (fallback)'self''unsafe-inline''unsafe-eval'https://cdn.example.comdata:
script-src-attr inline event handlersscript-src (fallback)'self''unsafe-inline''unsafe-eval'https://cdn.example.comdata:
style-src-elem stylesheets and style elementsstyle-src (fallback)'self''unsafe-inline'
style-src-attr style attributesstyle-src (fallback)'self''unsafe-inline'
worker-src workersscript-src (fallback)'self''unsafe-inline''unsafe-eval'https://cdn.example.comdata:
connect-src fetch, XHR, WebSocket, beaconsdefault-src (fallback)'self'
manifest-src web app manifestsdefault-src (fallback)'self'
object-src plugin contentdefault-src (fallback)'self'
frame-src framesdefault-src (fallback)'self'
media-src audio, video, tracksdefault-src (fallback)'self'
font-src fontsfont-srchttps://fonts.gstatic.com
img-src imagesimg-src*data:
base-uri the base elementunrestrictedanything
form-action form submission targetsunrestrictedanything
frame-ancestors who may embed this pageunrestrictedanything

A directive that is set replaces the fallback entirely: "There is no inheritance" (6.1.3). An unrestricted row means no directive in the chain is present, so that destination may load from anywhere.

10 findings

  1. highC14script-src'unsafe-inline'
    'unsafe-inline'

    'unsafe-inline' in script-src allows every inline script block, inline event handler and javascript: URL, which is what an XSS payload is. The specification's own reading: inline script is blocked "unless every policy allows inline script ... explicitly, by specifying 'unsafe-inline', a nonce-source or a hash-source" (6.1.10). Replace it with nonces or hashes; "nonces provide a substantial improvement over 'unsafe-inline'" (7.1).

  2. highC15script-src'unsafe-eval'
    'unsafe-eval'

    'unsafe-eval' in script-src allows eval(), Function(), and setTimeout or setInterval with a string: "The following JavaScript execution sinks are gated on the 'unsafe-eval' and 'trusted-types-eval' source expressions" (6.1.10). It is a global page flag, so an XSS that reaches any string sink becomes code.

  3. highC17script-srcA wildcard or bare scheme for script
    data:

    data: in script-src allows script from any data: URL. A bare scheme is an allowlist of the whole web, or, for data:, of whatever the attacker encodes inline; the specification's Strict CSP uses nonces or hashes instead and keeps https: only as a fallback behind 'strict-dynamic' (8.5).

  4. mediumC18script-srcA host allowlist for script
    https://cdn.example.com

    script-src allows script by host (https://cdn.example.com) without a nonce or hash. Host allowlists are the bypass class the specification itself describes: "Host- and path-based policies are tough to get right, especially on sprawling origins like CDNs" (8.2), and 8.5 recommends nonces or hashes with 'strict-dynamic' instead. Any JSONP endpoint, AngularJS copy or user-uploaded file on an allowed host executes.

  5. mediumC21base-uri

    No base-uri. An injected <base href> rewrites every relative URL on the page, scripts included, and base-uri has no fallback to default-src. The specification's Strict CSP: "base-uri: Specify a value of either 'self' or 'none'" (8.5).

  6. mediumC22frame-ancestors

    No frame-ancestors: any site can embed this page in a frame, which is the clickjacking class frame-ancestors exists for (6.4.2). It does not fall back to default-src: "a policy that declares default-src 'none' will still allow the resource to be embedded by anyone." Add frame-ancestors 'none' or 'self' to the header (it is ignored in meta).

  7. lowC14style-src'unsafe-inline'
    'unsafe-inline'

    'unsafe-inline' in style-src allows inline styles and style attributes. CSS injection is a lesser class than script injection, but it can exfiltrate data through selectors and background URLs; nonces or hashes work for style too.

  8. lowC19script-src'self' for script
    'self'

    'self' for script allows everything served by the page's own origin. It is fine as long as that origin serves no JSONP endpoint, no AngularJS or similar framework the attacker can drive, and no user-uploaded content; otherwise it is the bypass 8.2 describes.

  9. lowC20default-srcobject-src
    'self'

    Plugin content is allowed from 'self' (through default-src). Unless the page embeds plugins, object-src 'none' closes the sink entirely (6.1.9).

  10. noteC25Reporting

    No report-to and no report-uri: violations are blocked (or, in Report-Only, nothing happens) without anyone hearing of them. report-to names a Reporting API endpoint group (6.5.2); the specification suggests report-uri beside it for older browsers (6.5.1).

The other security headers (HSTS, X-Content-Type-Options, Referrer-Policy, COOP and the rest) are read by the secure headers checker. This page reads the policy's text against CSP Level 3 (W3C Working Draft, 16 September 2026) and grades it by the specification's own sentences; it does not fetch the page the policy protects, so it cannot know which inline scripts exist, whether a nonce really changes per response, or whether an allowed host serves JSONP. The host-allowlist findings are about the class, not a specific bypass. Several policies are evaluated one by one; when several are enforced, each must allow a load (8.1). Inputs over 20 000 characters are refused.

API endpointGEThttps://ronutz.com/api/v1/csp-evaluatorDocumented, not served. Opens the specification.

Références