Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Content Security Policy (CSP) Generator

Build a strict, working CSP with hashes, reporting and ready-to-paste server config.

Security No upload Works offline Free, no sign-up

Starting point

Import a policy you already have

On one line or several. All the response headers copied from your browser’s developer tools work too: the Content-Security-Policy header is picked out.

    Directives

    Type sources separated by spaces, or press the buttons. Keywords such as 'self' keep their single quotes; hosts do not (https://cdn.example.com).

    Add the origins a service needs

    From each provider’s own documentation. Services change: if something is still blocked, check their page.

    • Source For a property linked to Google Ads, Google lists more origins (https://*.google.<TLD> for each Google country domain, https://*.g.doubleclick.net, https://pagead2.googlesyndication.com) and frame-src https://www.googletagmanager.com.
    • Source Give the inline container snippet the nonce (Google’s recommended way) or add its hash. Each tag you fire may need more origins.
    • Source The CSS comes from fonts.googleapis.com and the font files from fonts.gstatic.com.
    • Source www.youtube-nocookie.com is YouTube’s privacy-enhanced embed mode.
    • Source
    • Source hooks.stripe.com is for payment methods that redirect (such as 3D Secure); maps.googleapis.com is needed only for the Address Element with your own Google Maps API key. Checkout, Link and Connect embedded components need other origins.
    • Source Google recommends the nonce-based approach; reCAPTCHA also works with 'strict-dynamic'.
    • Source With automatic setup on a proxied site the beacon reports to your own domain: connect-src 'self' is enough.

    Hashes for inline scripts and styles

    Paste code to get its hash.

      Enforce or test, and reporting

      Browsers block anything the policy does not allow.

      Your policy

       

      Review

        Strict CSP checklist (W3C CSP Level 3 §8.5, web.dev)

          Deliver it

           

            Next steps

            About the Content Security Policy (CSP) Generator

            A Content Security Policy (CSP) is an HTTP header that tells the browser which scripts, styles, images and other resources a page may use. A good one is the strongest safety net against cross-site scripting (XSS): even if an attacker gets a <script> into your page, the browser refuses to run it.

            This generator builds the policy with you. Start from a strict nonce- or hash-based CSP — the approach the W3C CSP Level 3 specification, Google’s web.dev guide and the OWASP cheat sheet recommend — or from a same-origin allowlist. Edit every directive with a check on each source, add the origins of services such as Google Analytics, Google Fonts or Stripe, and compute SHA-256, SHA-384 or SHA-512 hashes of your inline scripts and styles, or paste a whole page and let the tool find them. It reviews the result and writes it out as an HTTP header, a <meta> tag, or configuration for nginx, Apache, Caddy, Express, Cloudflare Pages, Netlify and Vercel — enforced or report-only. Everything runs in your browser.

            How to use it

            1. Pick a starting point: Strict, nonce-based for pages your server renders, Strict, hash-based for static or cached pages, or Same-origin allowlist if you cannot change your scripts yet.
            2. Edit the directives: type sources separated by spaces or press the buttons, add more directives from the list, and add the origins of the services you use.
            3. For a hash-based policy, paste each inline script exactly as it is between the tags — or scan your page’s HTML — and add the hashes.
            4. Choose Report only to test first, and enter a reporting URL to collect violation reports from real visitors.
            5. Read the review, fix everything marked Fix, then copy the policy or the configuration for your server.

            Examples

            Strict, nonce-based CSP
            Result
            script-src 'nonce-{NONCE}' 'strict-dynamic'; object-src 'none'; base-uri 'none'

            The policy web.dev and OWASP recommend. Your server puts a fresh random value in place of {NONCE} for every response and on each trusted <script nonce>.

            Hash of an inline script
            Input
            alert('Hello, world.');
            Result
            'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='

            The example used in the W3C CSP specification. Every character counts, including spaces and line breaks.

            Same-origin allowlist
            Result
            default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'; connect-src 'self'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'

            OWASP’s tightened basic policy with font-src and base-uri added: only your own origin, and no framing by other sites.

            Common uses

            • Adding a first CSP to a site, starting in report-only mode so nothing breaks.
            • Turning a weak allowlist policy with 'unsafe-inline' into a strict, nonce- or hash-based one.
            • Getting the hashes for inline scripts on a static site or single-page app.
            • Allowing Google Analytics, Tag Manager, Google Fonts, YouTube, Vimeo, Stripe, reCAPTCHA or Cloudflare Web Analytics without guessing the domains.
            • Writing the header for nginx, Apache, Caddy, Express, _headers or vercel.json.

            Strict CSP: nonces, hashes and 'strict-dynamic'

            Allowlists of hosts are hard to get right and often bypassable — for example through an old library or a JSONP endpoint on an allowed CDN — so the W3C (CSP Level 3 §8.5) and web.dev recommend trusting scripts by nonce or hash instead:

            • Nonce: your server creates a random value (at least 128 bits) for every response, sends script-src 'nonce-…' and writes the same value in each trusted <script nonce="…">. Use it for pages rendered per request.
            • Hash: the policy lists the SHA-256 (or 384/512) hash of each inline script. Use it for static and cached pages; load external scripts from a hashed inline loader.
            • 'strict-dynamic' lets a trusted script add more scripts, and makes modern browsers ignore host allowlists, 'self' and 'unsafe-inline'. web.dev lists support from Chrome 52, Edge 79, Firefox 52 and Safari 15.4; https: and 'unsafe-inline' can stay as fallbacks for older browsers.

            A strict policy blocks inline event handlers (onclick="…") and javascript: links: move them into scripts with addEventListener(). Add object-src 'none' and base-uri 'none' too.

            Rolling it out without breaking your site

            Send the policy as Content-Security-Policy-Report-Only first: browsers block nothing but report what they would block. To collect those reports, define an endpoint in the Reporting-Endpoints header and name it in report-to; add report-uri for older browsers (it is deprecated, and ignored when report-to is present). Watch the reports and the browser console, fix or allow what is legitimate, then switch to the enforcing header. Note that sandbox and upgrade-insecure-requests have no effect in report-only mode.

            Header or <meta> tag?

            Prefer the HTTP header. A <meta http-equiv="Content-Security-Policy"> tag cannot be report-only, ignores frame-ancestors, sandbox and report-uri (CSP Level 3 §3.3), and applies only to what comes after it, so it must be near the top of <head>. If a page gets both a header and a meta policy, both are enforced: a resource must pass each of them.

            Mistakes the review catches

            • Keywords without quotes: self means a host called self; write 'self'.
            • 'unsafe-inline' in script-src without a nonce or hash, which lets injected code run.
            • 'strict-dynamic' without any nonce or hash, which blocks every script.
            • 'none' together with other sources (it is then ignored).
            • Missing object-src and base-uri, and forgetting that base-uri, form-action and frame-ancestors do not fall back to default-src.
            • Wildcards and broad schemes such as https: or data: in script-src, http:// script hosts, IP addresses and non-Punycode domain names.
            • Hashes of the wrong length, nonces shorter than 128 bits or written into the policy as a fixed value (the configurations put a fresh one in for every response instead), and directives a <meta> tag or a report-only policy ignores.

            Limitations

            • The review checks the policy’s syntax and logic, not your live site. Test it in report-only mode on real pages before enforcing it; the Security Headers Checker shows the header a site actually sends.
            • Nonces have to come from your server, new for every response: the page shows where they go and example code, but cannot make them for you. Static configuration files cannot carry a nonce, so they are not offered for nonce policies.
            • Scanning HTML finds what is in the markup you paste. Scripts and styles added later by JavaScript, and inline code on your other pages, are not found.
            • Service origins come from each provider’s documentation; providers add domains over time, and some features (ads, maps, chat widgets) need more.
            • Browser support differs for newer parts of CSP Level 3, such as Trusted Types and the newer keywords.

            Privacy

            Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.

            Frequently asked questions

            What is the best Content Security Policy for my site?

            A strict one: script-src with a nonce (or hashes) and 'strict-dynamic', plus object-src 'none' and base-uri 'none'. It blocks injected scripts without a long list of hosts. Add frame-ancestors 'none' or 'self' against clickjacking, and roll it out in report-only mode first.

            Should I use a nonce or a hash?

            Use a nonce when your server renders each page, because it can put a new random value in the header and the HTML every time. Use hashes when pages are static files or cached, since the hash of a script never changes while the script stays the same.

            Why is my inline script still blocked after I added its hash?

            The hash covers every character between <script> and </script>: an extra space or line break, a different quote, or a later edit changes it. Also check that the hash is in the directive that applies (script-src-elem overrides script-src for <script> elements), and that event handlers and style attributes need 'unsafe-hashes' as well. The browser console names the hash it expected.

            Can I set a CSP in a <meta> tag?

            Yes, for sites where you cannot set headers, but with limits: no report-only mode, no frame-ancestors, sandbox or report-uri, and it must come before the scripts and styles it should cover. The <meta> tag format leaves out what a meta policy ignores and tells you.

            What does 'strict-dynamic' do?

            It passes trust on: a script allowed by nonce or hash may load more scripts (with createElement('script')), and those run too. At the same time, modern browsers ignore host and scheme allowlists and 'self' in that directive, so only nonces and hashes decide what starts.

            Does frame-ancestors replace X-Frame-Options?

            Yes. When an enforced policy has frame-ancestors, browsers ignore X-Frame-Options (CSP Level 3, §6.4.2). Some sites still send both for very old browsers.

            Is my policy or HTML sent anywhere?

            No. The policy, the hashes and any HTML you scan are handled in your browser; nothing is uploaded. Your policy draft is remembered in this browser only, so you can come back to it.

            Quick answers and tool search

            Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.