Skip to main content

CSP Analyzer

Available
Security

Analyze Content Security Policy headers, understand directives, detect risky configurations, and generate clearer CSP policies.

CSP Analyzer tool

CSP input

CSP policies are analyzed locally in your browser. DevCraftKit does not store or upload the policy you enter.

Enforcing policies block what they do not allow.

Paste the policy alone, or a full header line such as Content-Security-Policy: ... or Content-Security-Policy-Report-Only: .... The header name is detected and removed automatically, and a Report-Only header overrides the tab above. Apache Header set and nginx add_header lines also work. Press Ctrl/Cmd+Enter to analyze.

No analysis yet

Paste a Content-Security-Policy above (or load an example) and choose Analyze CSP to see directives, findings with evidence and context, a plain-English explanation and a normalized policy.

Compare Policies

Paste two policies to see which directives and sources were added, removed or changed. The comparison describes differences only; it does not say which policy is better, because that depends on what your application needs.

Generate CSP

Tell the generator what your application loads and it builds a starting policy from exactly that. It does not try to produce a universally “secure” policy, because the right policy depends on your application.

Baseline
Same-origin resources
External services (host names)
Hardening

CSP Directive Reference

What each directive controls, typical usage, an example and common mistakes. Browser support differs by directive and specification level, so check your target browsers before relying on newer directives.

default-srcFetch directive

Controls: The fallback for the other fetch directives. If a more specific fetch directive such as img-src or script-src is absent, the browser uses default-src for that resource type instead.

Typical usage: Set a restrictive baseline (often 'self' or 'none') and then loosen individual resource types with specific directives.

Example

default-src 'self'; img-src 'self' https://images.example.com

Common mistakes

  • Assuming default-src covers every CSP directive. It does not apply to base-uri, form-action, frame-ancestors, sandbox or the reporting directives.
  • Setting a restrictive default-src and then adding a broad script-src (or the reverse), which makes the effective rules harder to reason about.
  • Forgetting that a specific directive replaces default-src for that resource type rather than adding to it.

Standards and browser support: Part of CSP Level 1. Fallback behaviour for newer directives (script-src-elem, worker-src and others) is defined in CSP Level 3.

script-srcFetch directive

Controls: Where JavaScript may be loaded from and whether inline scripts and string-to-code APIs such as eval() are allowed. It also applies to WebAssembly compilation and, as a fallback, to workers.

Typical usage: List the origins you load scripts from, or use nonce/hash sources (optionally with 'strict-dynamic') instead of a long host allowlist.

Example

script-src 'self' https://cdn.example.com

Common mistakes

  • Adding 'unsafe-inline' to make inline scripts work, which removes most of the protection script-src provides against injected inline script.
  • Allowing a wide host (a public CDN or a wildcard) that serves scripts the application does not use.
  • Using a static nonce value instead of a fresh unpredictable value on each response.

When absent, falls back to: default-src

Standards and browser support: CSP Level 1. Nonce and hash sources arrived in Level 2; 'strict-dynamic' in Level 3. Browser support for individual keywords differs.

script-src-elemFetch directive

Controls: Where <script> elements may load code from, and which inline <script> blocks are allowed. Overrides script-src for script elements only.

Typical usage: Use together with script-src-attr to apply different rules to script elements and inline event handlers.

Example

script-src-elem 'self' 'nonce-r4nd0m'

Common mistakes

  • Setting it more loosely than script-src and forgetting that it takes precedence for <script> elements.
  • Expecting it to affect inline event-handler attributes (that is script-src-attr).

When absent, falls back to: script-src → default-src

Standards and browser support: CSP Level 3. Not recognised by older browsers, which then fall back to script-src.

script-src-attrFetch directive

Controls: Whether inline event-handler attributes such as onclick="..." may run. Overrides script-src for those attributes only.

Typical usage: script-src-attr 'none' blocks inline event handlers while still allowing script elements governed by script-src.

Example

script-src-attr 'none'

Common mistakes

  • Allowing 'unsafe-inline' here to keep a few legacy onclick handlers working and thereby re-enabling all inline handlers.
  • Using hashes without 'unsafe-hashes', which do not match event-handler attributes.

When absent, falls back to: script-src → default-src

Standards and browser support: CSP Level 3. Not recognised by older browsers, which then fall back to script-src.

style-srcFetch directive

Controls: Where stylesheets may load from and whether inline <style> blocks and style attributes are allowed.

Typical usage: Allow your own origin and any style CDN. Prefer nonces or hashes over 'unsafe-inline' when inline styles are required.

Example

style-src 'self' https://fonts.googleapis.com

Common mistakes

  • Adding 'unsafe-inline' for convenience with UI libraries without checking whether nonces or hashes would work.
  • Forgetting that style-src does not control font files (font-src does).

When absent, falls back to: default-src

Standards and browser support: CSP Level 1. Nonce and hash sources arrived in Level 2.

style-src-elemFetch directive

Controls: Where <style> and <link rel=stylesheet> elements may load styles from. Overrides style-src for those elements.

Typical usage: Use together with style-src-attr to treat style elements and style attributes differently.

Example

style-src-elem 'self' https://fonts.googleapis.com

Common mistakes

  • Forgetting that it takes precedence over style-src for stylesheet elements.

When absent, falls back to: style-src → default-src

Standards and browser support: CSP Level 3. Older browsers fall back to style-src.

style-src-attrFetch directive

Controls: Whether inline style="..." attributes are allowed. Overrides style-src for those attributes.

Typical usage: Allow inline style attributes only where needed while keeping style elements strict.

Example

style-src-attr 'unsafe-inline'

Common mistakes

  • Expecting a nonce to allow style attributes; nonces apply to elements, not attributes.

When absent, falls back to: style-src → default-src

Standards and browser support: CSP Level 3. Older browsers fall back to style-src.

img-srcFetch directive

Controls: Where images and favicons may load from.

Typical usage: List your image hosts. data: is commonly added for inline images and blob: for generated ones.

Example

img-src 'self' data: https://images.example.com

Common mistakes

  • Using * when only a few image hosts are needed.
  • Allowing http: images on an HTTPS page, which is mixed content.

When absent, falls back to: default-src

Standards and browser support: CSP Level 1.

font-srcFetch directive

Controls: Where web fonts loaded with @font-face may come from.

Typical usage: Allow your own origin and your font provider's file host.

Example

font-src 'self' https://fonts.gstatic.com

Common mistakes

  • Allowing a font stylesheet host in style-src but forgetting the separate host that serves the font files in font-src.

When absent, falls back to: default-src

Standards and browser support: CSP Level 1.

connect-srcFetch directive

Controls: Which URLs script code may connect to with fetch(), XMLHttpRequest, WebSocket, EventSource, navigator.sendBeacon() and the ping attribute.

Typical usage: List your API origins and WebSocket endpoints. A tight connect-src limits where injected script could send data.

Example

connect-src 'self' https://api.example.com wss://realtime.example.com

Common mistakes

  • Forgetting wss:// endpoints, since 'self' is matched against the document's scheme and host.
  • Using * and losing control over where data can be sent.

When absent, falls back to: default-src

Standards and browser support: CSP Level 1.

media-srcFetch directive

Controls: Where <audio>, <video> and <track> resources may load from.

Typical usage: List the origins that host your media files.

Example

media-src 'self' https://media.example.com

Common mistakes

  • Forgetting blob: when media is generated or streamed with MediaSource.

When absent, falls back to: default-src

Standards and browser support: CSP Level 1.

object-srcFetch directive

Controls: Where <object>, <embed> and legacy <applet> plugin content may load from.

Typical usage: object-src 'none' is commonly recommended when the site does not need plugins.

Example

object-src 'none'

Common mistakes

  • Leaving it unset on a policy without default-src, which leaves plugin content unrestricted.
  • Assuming 'none' in default-src and a broad object-src are the same; the specific directive wins.

When absent, falls back to: default-src

Standards and browser support: CSP Level 1. Browser plugins are largely obsolete, but the directive is still widely recommended as a hardening step.

frame-srcFetch directive

Controls: Which URLs may be loaded into nested browsing contexts such as <iframe> and <frame> elements on this page.

Typical usage: List the third-party embeds the page uses (video players, payment forms, maps).

Example

frame-src https://www.youtube-nocookie.com

Common mistakes

  • Confusing frame-src (what this page may embed) with frame-ancestors (who may embed this page).
  • Allowing https: when a handful of providers are needed.

When absent, falls back to: child-src → default-src

Standards and browser support: CSP Level 1 (deprecated in Level 2, restored in Level 3). Falls back to child-src, then default-src.

child-srcFetch directive

Controls: Where web workers and nested browsing contexts (frames) may load from. It is a fallback for frame-src and worker-src.

Typical usage: Use frame-src and worker-src for new policies; child-src mostly appears in older policies.

Example

child-src 'self'

Common mistakes

  • Expecting child-src to override frame-src or worker-src; the specific directives win.

When absent, falls back to: default-src

Standards and browser support: Introduced in CSP Level 2 and kept as a fallback in Level 3.

worker-srcFetch directive

Controls: Where Worker, SharedWorker and ServiceWorker scripts may load from.

Typical usage: Allow your own origin, plus blob: if the application creates workers from Blob URLs.

Example

worker-src 'self' blob:

Common mistakes

  • Forgetting that a worker script is script execution; a broad worker-src weakens the script policy.
  • Missing blob: for libraries that spawn workers from Blob URLs.

When absent, falls back to: child-src → script-src → default-src

Standards and browser support: CSP Level 3. Falls back to child-src, then script-src, then default-src.

manifest-srcFetch directive

Controls: Where the Web App Manifest file referenced by <link rel=manifest> may load from.

Typical usage: Usually 'self'.

Example

manifest-src 'self'

Common mistakes

  • Forgetting it when default-src is restrictive and the site ships a PWA manifest from a different origin.

When absent, falls back to: default-src

Standards and browser support: CSP Level 3.

prefetch-srcDeprecated / obsolete

Controls: Where resources may be prefetched or prerendered from. It was proposed for CSP Level 3 and later removed from the specification.

Typical usage: Avoid in new policies; browsers do not broadly implement it.

Example

prefetch-src 'self'

Common mistakes

  • Relying on it for protection; support is minimal.

When absent, falls back to: default-src

Standards and browser support: Removed from the CSP specification. Treat as having little or no effect.

fenced-frame-srcFetch directive

Controls: Which URLs may be loaded into <fencedframe> elements.

Typical usage: Relevant only for pages that embed fenced frames.

Example

fenced-frame-src https://ads.example.com

Common mistakes

  • Assuming broad browser support; fenced frames are a newer, Chromium-led feature.

When absent, falls back to: default-src

Standards and browser support: Defined by the Fenced Frame specification; support is limited to some Chromium-based browsers.

webrtcFetch directive

Controls: Controls whether WebRTC connections may be established ('allow' or 'block').

Typical usage: Relevant only for pages that need to restrict WebRTC.

Example

webrtc 'block'

Common mistakes

  • Assuming broad browser support; this is a newer, Chromium-led directive.

Standards and browser support: Limited browser support.

base-uriDocument directive

Controls: Which URLs may be used in the <base> element. It does not fall back to default-src.

Typical usage: base-uri 'self' or base-uri 'none' stops injected <base> tags from redirecting relative URLs elsewhere.

Example

base-uri 'self'

Common mistakes

  • Omitting it, assuming default-src covers it (it does not).
  • Using nonce-based script policies without base-uri, which leaves relative script URLs open to <base> injection.

Standards and browser support: CSP Level 2.

form-actionNavigation directive

Controls: Which URLs may be used as the target of form submissions. It does not fall back to default-src.

Typical usage: form-action 'self' limits forms to submitting to your own origin.

Example

form-action 'self' https://payments.example.com

Common mistakes

  • Assuming default-src restricts forms (it does not).
  • Forgetting a payment or login provider that forms post to.

Standards and browser support: CSP Level 2. Redirect handling after a form submission differs between browsers.

frame-ancestorsNavigation directive

Controls: Which origins may embed this page in a frame, iframe, object or embed. This is the CSP equivalent of X-Frame-Options and is the main CSP control against clickjacking.

Typical usage: frame-ancestors 'none' blocks all embedding; 'self' allows same-origin embedding; list origins to allow specific embedders.

Example

frame-ancestors 'none'

Common mistakes

  • Confusing it with frame-src. frame-ancestors controls who can frame your page; frame-src controls what your page can frame.
  • Setting it in a <meta> tag or Report-Only policy, where it is not applied.
  • Expecting default-src to cover it.

Standards and browser support: CSP Level 2. Not supported in <meta> policies.

navigate-toDeprecated / obsolete

Controls: A proposed directive limiting where the document can navigate to. It is not part of the current CSP specification and is not broadly implemented.

Typical usage: Avoid in new policies.

Example

navigate-to 'self'

Common mistakes

  • Relying on it for protection; major browsers do not implement it.

Standards and browser support: Removed from the CSP specification drafts. Treat as having little or no effect.

sandboxDocument directive

Controls: Applies iframe-style sandbox restrictions to the protected document. With no value it applies every restriction; tokens such as allow-scripts and allow-forms relax individual ones.

Typical usage: Use for pages that should run with reduced privileges, adding only the allow-* tokens they need.

Example

sandbox allow-scripts allow-forms

Common mistakes

  • Combining allow-scripts with allow-same-origin and expecting strong isolation.
  • Using sandbox in a <meta> tag or Report-Only policy, where it is ignored.

Standards and browser support: CSP Level 1. Not supported in <meta> policies and ignored in Content-Security-Policy-Report-Only.

require-trusted-types-forTrusted Types

Controls: Requires Trusted Types objects, rather than plain strings, for DOM XSS sinks such as innerHTML and eval-like functions. The only defined value is 'script'.

Typical usage: require-trusted-types-for 'script' is typically paired with a trusted-types directive naming the allowed policies.

Example

require-trusted-types-for 'script'; trusted-types app-policy

Common mistakes

  • Enabling it without first defining Trusted Types policies, which breaks pages that write strings to sinks.
  • Expecting support in every browser.

Standards and browser support: Trusted Types are implemented in Chromium-based browsers; other browsers' support is limited or newer.

trusted-typesTrusted Types

Controls: Lists the Trusted Types policy names the page may create with trustedTypes.createPolicy(). 'none' forbids creating any policy; 'allow-duplicates' permits reusing a name.

Typical usage: Name only the policies your code needs, together with require-trusted-types-for 'script'.

Example

trusted-types app-policy 'allow-duplicates'

Common mistakes

  • Setting trusted-types without require-trusted-types-for 'script', which restricts policy creation but does not enforce the sink requirement.
  • Using * so any policy name is accepted.

Standards and browser support: Implemented in Chromium-based browsers; support elsewhere is limited.

upgrade-insecure-requestsUpgrade directive

Controls: Tells the browser to treat insecure (http) URLs for subresources and same-origin navigations as if they were https.

Typical usage: Useful while migrating a site to HTTPS; it takes no value.

Example

upgrade-insecure-requests

Common mistakes

  • Treating it as a replacement for a proper HTTPS configuration and redirects.
  • Expecting it to fix resources whose hosts do not serve HTTPS.

Standards and browser support: Part of the Upgrade Insecure Requests specification; widely supported in current browsers.

block-all-mixed-contentDeprecated / obsolete

Controls: Blocks all mixed content (http resources on an https page), including content browsers would otherwise load with a warning.

Typical usage: Largely superseded by browsers' built-in mixed-content handling and by upgrade-insecure-requests.

Example

block-all-mixed-content

Common mistakes

  • Presenting it as a substitute for serving everything over HTTPS.

Standards and browser support: Deprecated. Modern browsers already block or upgrade most mixed content.

plugin-typesDeprecated / obsolete

Controls: Restricted the MIME types of plugins that could be loaded. It has been removed from the specification.

Typical usage: Do not use; prefer object-src 'none'.

Example

plugin-types application/pdf

Common mistakes

  • Keeping it for protection; browsers have dropped it.

Standards and browser support: Removed from the CSP specification.

referrerDeprecated / obsolete

Controls: An obsolete CSP directive that set the referrer policy. Use the Referrer-Policy header instead.

Typical usage: Do not use; send a Referrer-Policy header.

Example

referrer no-referrer

Common mistakes

  • Expecting it to take effect in current browsers.

Standards and browser support: Obsolete.

reflected-xssDeprecated / obsolete

Controls: An obsolete directive that controlled browsers' built-in reflected XSS filters. Those filters have been removed from current browsers.

Typical usage: Do not use.

Example

reflected-xss block

Common mistakes

  • Expecting it to take effect in current browsers.

Standards and browser support: Obsolete.

report-uriReporting

Controls: One or more URLs that should receive JSON violation reports when the policy is violated.

Typical usage: Point it at an endpoint that accepts CSP violation reports. Often paired with report-to.

Example

report-uri https://csp.example.com/report

Common mistakes

  • Pointing at an endpoint that does not accept POSTed reports.
  • Using an http:// endpoint, which sends reports unencrypted.

Standards and browser support: Deprecated in favour of report-to in the specification, but still widely used because browser support for report-to has been less consistent.

report-toReporting

Controls: The name of a reporting group (defined with the Reporting-Endpoints or Report-To response header) that receives violation reports.

Typical usage: Define the group in a Reporting-Endpoints header and reference its name here.

Example

report-to csp-endpoint

Common mistakes

  • Naming a group that is not defined in a separate header, in which case nothing is reported.
  • Providing a URL instead of a group name.

Standards and browser support: Part of the Reporting API; browser support varies.

About Content Security Policy

What Is Content Security Policy?

Content Security Policy (CSP) is a web platform security feature that lets a site declare which sources the browser may use for scripts, styles, images, fonts, frames, network connections and other resources, and what inline code may do. A page that receives a policy applies it to everything it loads and runs; anything that does not match is blocked and can be reported.

CSP exists mainly to limit the damage of content injection, such as cross-site scripting (XSS), and to give sites control over third-party content. It is a defense-in-depth layer, not a substitute for fixing injection bugs. This CSP Analyzer, which you can also think of as a CSP checker, CSP validator and Content Security Policy analyzer, helps you read and review a policy; it cannot tell you whether the policy is sufficient for your application.

What Does a CSP Header Do?

The policy normally arrives in the Content-Security-Policy HTTP response header for each document. The browser parses it into directives and, as the page loads, checks every subresource request and several script behaviors against them. If a check fails, the resource is not loaded, the action is refused, a message appears in the console, and a violation report may be sent to an endpoint you configure.

Headers are not the only delivery method: a <meta http-equiv="Content-Security-Policy"> element works for many directives, but not for frame-ancestors, report-uri or sandbox. To see the headers your site actually sends, use the HTTP Security Headers Analyzer, which reviews CSP alongside HSTS, X-Content-Type-Options and other response headers, and the Redirect Chain Analyzer when you need to see what each hop in a redirect chain returns.

How to Read a CSP Policy

A policy is a list of directives separated by semicolons. Each directive is a name followed by zero or more values, usually source expressions:

default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'

Read it one directive at a time. Here, anything without its own directive may load from the page's own origin; scripts may also load from cdn.example.com; and plugin content is blocked. The most common source expressions are:

  • 'self' - the document's origin (scheme, host and port)
  • 'none' - nothing is allowed
  • https://cdn.example.com - a specific host, optionally with port and path
  • https://*.example.com - matching subdomains
  • https: or data: - an entire scheme
  • 'nonce-...', 'sha256-...' - authorize specific inline content
  • 'unsafe-inline', 'unsafe-eval' - relax inline and eval restrictions
  • 'strict-dynamic' - trust scripts loaded by trusted scripts

The “Explain Policy” section of the tool rewrites each directive in plain English, and the Source Inspector breaks every source into scheme, host, port and path.

CSP Directives Explained

Directives fall into groups. The directive reference above covers each one in detail.

  • Fetch directives control where resources load from: default-src, script-src, style-src, img-src, font-src, connect-src, media-src, object-src, frame-src, worker-src, manifest-src and the -elem/-attr variants for script and style.
  • Document directives govern the document itself: base-uri and sandbox.
  • Navigation directives govern where a page can send users or data and who can embed it: form-action and frame-ancestors.
  • Reporting: report-uri and report-to.
  • Other: upgrade-insecure-requests, block-all-mixed-content (deprecated), require-trusted-types-for and trusted-types.

Browser support is uneven for newer directives, so check the browsers you target. The analyzer reports an unrecognized directive as such rather than calling it invalid.

What Is default-src?

default-src is the fallback for most fetch directives. If img-src is absent, images follow default-src; if it is present, img-src applies and default-src is ignored for images. It does not apply to base-uri, form-action, frame-ancestors, sandbox or the reporting directives, so a policy that sets only default-src leaves those unrestricted. A specific directive replaces default-src for its resource type rather than adding to it, which is a frequent source of surprises.

What Is script-src?

script-src controls where JavaScript can come from and whether inline scripts and eval() are allowed. It is the directive most closely tied to XSS mitigation, so the analyzer checks it most closely: broad wildcards, https: and data: sources, HTTP sources, shared CDN hosts, 'unsafe-inline', 'unsafe-eval', nonces, hashes and 'strict-dynamic'. script-src-elem and script-src-attr can apply different rules to script elements and inline event handlers. Workers fall back to worker-src, then script-src.

What Does unsafe-inline Mean?

'unsafe-inline' allows inline code. In script-src that means inline <script> blocks, event-handler attributes and javascript: URLs, so injected markup can run script. In style-src it allows inline <style> blocks and style attributes, which is generally a smaller risk. The effect depends on the directive it appears in, and the analyzer words its findings accordingly.

It also depends on what else is in the list. Browsers that support nonces or hashes ignore 'unsafe-inline' when the same source list contains one, and browsers that support 'strict-dynamic' ignore it in script directives, so the keyword is sometimes kept deliberately as a fallback for old browsers.

What Does unsafe-eval Mean?

'unsafe-eval' allows eval(), new Function() and string arguments to setTimeout() and setInterval(). Some template engines, bundler development modes and older libraries rely on them. Its presence is a prompt to ask whether the dependency can be updated or precompiled; it does not mean the application is vulnerable. 'wasm-unsafe-eval' permits WebAssembly compilation without permitting eval().

What Is a CSP Nonce?

A nonce is a per-response random value. The server places it in the header (script-src 'nonce-r4nd0m') and on each allowed element (<script nonce="r4nd0m">). The browser runs only elements with a matching nonce, so an attacker who injects a script tag cannot guess it. That depends on the nonce being unpredictable and new on every response, which a static analyzer cannot verify, so a CSP nonce checker can confirm the syntax and flag values that look static or short, but not that your implementation is sound.

Content-Security-Policy: script-src 'nonce-4AEemGb0xJptoIGFP3Nd'; object-src 'none'; base-uri 'none'

What Is a CSP Hash?

A hash source allows an inline script or style by its digest: 'sha256-<base64>', with sha384 and sha512 also supported. It suits static inline snippets because any change to the content changes the digest. The analyzer is a CSP hash checker for syntax - the algorithm, base64 form and length - but it has no access to your page, so it cannot confirm that a hash matches deployed content. Browsers print the expected hash in their console message when a hash is missing.

What Is strict-dynamic?

'strict-dynamic' extends trust from a nonce- or hash-authorized script to the scripts it loads. In browsers that support it, host and scheme sources, 'self' and 'unsafe-inline' in that list are ignored, so the allowlist stops mattering and trust comes from the nonce or hash. Browsers without support ignore the keyword and fall back to the allowlist. Without any nonce or hash there is nothing to start the trust chain, so scripts may be blocked entirely. It is useful for applications whose trusted scripts load others dynamically, and is not required for every policy.

script-src 'nonce-4AEemGb0xJptoIGFP3Nd' 'strict-dynamic' https: 'unsafe-inline'

The example above is a known compatibility pattern: supporting browsers use the nonce and ignore the rest, while older browsers fall back to https: and 'unsafe-inline'.

CSP Report-Only vs Enforcing

Content-Security-Policy enforces: violations are blocked. Content-Security-Policy-Report-Only only reports: nothing is blocked, and violations show in the console and, if configured, at a report-uri or report-to endpoint. Report-Only is the safe way to test a new policy, and the analyzer labels the policy type at the top of its results so the two are never confused. A page can send both headers, and they are evaluated independently.

Common CSP Mistakes

  • Writing self or none without quotes. Without quotes they are treated as host names, not keywords.
  • Assuming default-src controls base-uri, form-action or frame-ancestors; it does not.
  • Adding 'unsafe-inline' to script-src to get a page working, which removes most of the protection.
  • Allowing an entire public CDN or https: in script-src, which allows many scripts you do not use.
  • Repeating a directive: browsers use the first occurrence and ignore the rest.
  • Mixing up frame-src (what you embed) and frame-ancestors (who embeds you).
  • Using a static nonce or a placeholder value copied from documentation.
  • Setting frame-ancestors, report-uri or sandbox in a meta tag, where they are not supported.
  • Deploying an enforcing policy without testing it in Report-Only first.

How to Fix CSP Errors

Open the browser console and read the violation message: it names the blocked URL and the directive that blocked it. Decide whether the resource is legitimate. If it is, add the exact origin to the specific directive that blocked it. If it is inline code, prefer moving it to a file or authorizing it with a nonce or hash over adding 'unsafe-inline'. If it is not legitimate, leave it blocked and find out where the request comes from. Iterate with a Report-Only header so visitors are not affected.

If your violation reports or console output contain tokens, user IDs or internal hostnames, remove them before sharing; the Log Sanitizer does that locally in your browser. Reports sent to report-uri are JSON, which the JSON Formatter can pretty-print for reading.

How to Create a CSP

A workable approach, which the generator above follows:

  1. List what the page actually loads: your own origin, CDNs, fonts, analytics, APIs, WebSockets and embeds.
  2. Start from a restrictive baseline (default-src 'none' or 'self') and add specific directives for each resource type.
  3. Add object-src 'none', base-uri, form-action and frame-ancestors, which default-src does not cover.
  4. Prefer nonces or hashes to 'unsafe-inline' for scripts.
  5. Deploy as Content-Security-Policy-Report-Only with a reporting endpoint, review the reports, then enforce.

On Apache you can set the header in configuration or .htaccess with Header set Content-Security-Policy "..."; the .htaccess Analyzer checks that file, and this tool accepts a pasted Header set line directly.

Header always set Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'"

CSP and XSS Protection

CSP can limit what injected content can do: with a strict policy, an injected inline script or a script from an unexpected origin is blocked. It does not remove the underlying bug, and policies that allow 'unsafe-inline', broad hosts or injectable endpoints give much less protection. Think of CSP as a second line of defense behind output encoding, input handling and safe templating. The analyzer shows what a policy permits; whether that is enough is a judgement about your application, and no tool can declare a site secure.

CSP behavior depends on browser support and the CSP specification level. The analyzer focuses on policy syntax and commonly implemented behavior and does not claim universal browser compatibility.

Did this help you make sense of a CSP?

If these free developer tools save you time, consider buying me a byte. Your support helps keep DevCraftKit free and growing.

Buy me a byte 💾

Resources

View all

Explore more developer tools

Browse the full collection, or see everything in Security.

CSP Analyzer FAQ

What is CSP?
CSP stands for Content Security Policy. It is a browser security mechanism, delivered mostly as the Content-Security-Policy HTTP response header, that tells the browser which sources a page may load scripts, styles, images, fonts, frames and other resources from, and what the page may do with inline code. When a resource or action does not match the policy, the browser blocks it and can report the violation. CSP is a defense-in-depth layer: it can reduce the impact of some injection bugs, but it does not replace fixing them.
What is a CSP analyzer?
A CSP analyzer reads a Content Security Policy, breaks it into directives and source expressions, checks the syntax and flags configurations worth reviewing, such as 'unsafe-inline', wildcards, insecure schemes and duplicate directives. This one is rule-based and runs in your browser. It reports evidence and context for each finding rather than a single score, because how strong a policy is depends on how your application works.
How do I check my Content Security Policy?
Copy the value of the Content-Security-Policy header from your browser's developer tools (Network tab, select the document request, Response Headers) or from curl -I, paste it into the analyzer above and choose Analyze CSP. You can paste the whole header line; the header name is removed automatically. Then test the policy in a real browser, because only a browser can tell you whether your pages still work under it.
curl -sI https://example.com | grep -i content-security-policy
How do I validate a CSP header?
Validation has two parts. Syntax: directives separated by semicolons, each with a valid name and well-formed source expressions (quoted keywords such as 'self', nonces, hashes, schemes and hosts). Behavior: whether the policy allows what your pages need and blocks what they should not. The analyzer covers the syntax side and highlights risky or unclear settings; the behavior side needs testing in a browser, ideally with a Report-Only header first.
What does unsafe-inline mean in CSP?
'unsafe-inline' allows inline code that CSP would otherwise block. In script-src it permits inline script blocks, inline event-handler attributes such as onclick and javascript: URLs, which removes much of the protection against injected script. In style-src it permits inline style blocks and style attributes, which is generally a smaller risk. If the same source list also contains a nonce or hash, browsers that support them ignore 'unsafe-inline', so it then acts only as a fallback for older browsers.
What does unsafe-eval mean?
'unsafe-eval' permits string-to-code APIs that CSP otherwise blocks, including eval(), new Function() and setTimeout() or setInterval() called with a string. Some frameworks and older libraries need it, and its presence does not by itself mean an application is vulnerable, but it means data that reaches those APIs can run as code. If you only need WebAssembly, 'wasm-unsafe-eval' is a narrower option.
What is a CSP nonce?
A nonce is a random value that the server generates for each response, puts in the policy as a nonce-prefixed value and also adds as a nonce attribute on each inline script or style it wants to allow. The browser runs only the elements whose nonce matches. For this to help, the value must be unpredictable (at least 128 bits from a secure random source) and different on every response. A static or reused nonce gives no protection, and an analyzer that only sees the policy cannot tell how your server generates it.
What is a CSP hash?
A hash source such as 'sha256-...' contains the base64 digest of a specific inline script or style. The browser allows inline content only if its digest matches. Hashes suit static inline snippets: any change to the content, including whitespace, changes the digest. In CSP Level 3 a hash can also allow an external script that has a matching integrity attribute. The analyzer can check that a hash is well-formed but cannot confirm that it matches your deployed content.
What is strict-dynamic?
'strict-dynamic' lets a script that is already trusted through a nonce or hash load further scripts without each one being listed. In browsers that support it, host and scheme sources, 'self' and 'unsafe-inline' in the same script-src list are ignored, so trust flows from the nonce or hash instead of from an allowlist. Browsers that do not support it ignore the keyword and use the allowlist, which is why some policies keep both. It is not required for every policy and is mainly useful when trusted scripts inject others dynamically.
What is CSP Report-Only?
Content-Security-Policy-Report-Only is a header that evaluates a policy and reports violations without blocking anything. It is meant for testing a new or stricter policy against real traffic before enforcing it. Violations still appear in the browser console, and are sent to your endpoint if you add report-uri or report-to. Some directives, such as sandbox, are not applied in Report-Only mode. When the reports are clean, send the same policy in the Content-Security-Policy header.
What is the difference between CSP and CORS?
They solve different problems. CSP restricts what a page is allowed to load and do, and is set by the page being protected. CORS controls whether a page from one origin may read responses from another origin, and is set by the server being requested. CSP's connect-src can limit where a page's scripts may send requests, while CORS decides whether the browser lets the page read the response; one does not substitute for the other.
Does CSP protect against XSS?
A well-designed CSP can make cross-site scripting harder to exploit, for example by blocking inline script and scripts from unexpected origins. It is a mitigation, not a guarantee: allowlists that are too broad, 'unsafe-inline', 'unsafe-eval', injectable base elements and trusted endpoints that can be abused can all weaken it, and CSP does not remove the underlying bug. Output encoding, input validation and safe frameworks remain the primary defenses.
How do I fix CSP errors?
Open the browser console: each violation names the directive that blocked the resource and the blocked URL. Decide whether the resource is legitimate. If so, add its origin to the specific directive (for example a font host to font-src, not to default-src), or for inline code use a nonce or hash instead of 'unsafe-inline'. If the resource is not legitimate, leave it blocked and find out why the page requests it. Use Report-Only while you iterate.
What should a CSP contain?
It depends on the application, so there is no single required list. Commonly useful directives are default-src as a restrictive fallback, a script-src based on 'self' and nonces or hashes, object-src 'none', base-uri, form-action and frame-ancestors, plus a reporting endpoint. The generator in this tool builds a starting policy from what your application loads; treat it as a draft to test, not a finished policy.
Is default-src required?
No. default-src is optional. It is a fallback for fetch directives that you did not set (script-src, style-src, img-src, font-src, connect-src and others), so it is a convenient baseline, but a policy without it is valid. It does not cover base-uri, form-action, frame-ancestors, sandbox or the reporting directives, which need their own entries.
Why is object-src 'none' commonly used?
object-src controls object, embed and legacy applet content. Plugin content has historically been a way to run code outside the script-src rules, and most sites no longer need it, so object-src 'none' removes that route at little cost. Without object-src or a default-src to fall back on, plugin content is not restricted by the policy.
What is frame-ancestors?
frame-ancestors specifies which origins may embed your page in a frame, iframe, object or embed. It is the CSP control against clickjacking and the modern counterpart of X-Frame-Options. frame-ancestors 'none' blocks all embedding, 'self' allows same-origin embedding, and a list of origins allows specific embedders. It is ignored in policies delivered through a meta tag and does not fall back to default-src.
What is the difference between frame-src and frame-ancestors?
They point in opposite directions. frame-src controls what your page may load into frames - the pages and widgets you embed. frame-ancestors controls who may embed your page. A site that embeds a video player needs the player's origin in frame-src; a site that wants to stop others from framing it sets frame-ancestors. Mixing the two up is a common CSP mistake.
Does the CSP Analyzer upload my policy?
No. The analysis is a deterministic, rule-based parser that runs in your browser. The policy you paste is not sent anywhere or stored, the tool works offline once the page has loaded, and exports are generated on your device.

Found a bug or an incorrect result in CSP Analyzer?

Report it, or suggest an improvement. Messages go straight to the developer.

Send feedback