VibeSecurity

Free tool, runs in your browser

Build and check a Content-Security-Policy

Edit every directive, add the origins popular services need with one click, or paste the policy you already have and see what is weak. Export it as a header, for Next.js, Vercel, Netlify, Cloudflare Pages, nginx or a meta tag.

Add a service

Presets for Stripe, Google Analytics, Turnstile and PostHog follow each vendor's CSP documentation. The others are based on the hosts those services load from. Always confirm in report-only mode.

Directives

script-src

Where JavaScript may load and run from. The most important directive.

'self'
Other settings

Adds report-uri for older browsers, and report-to with a matching Reporting-Endpoints header for newer ones.

HTTP response header

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'; object-src 'none'; upgrade-insecure-requests

Report-only logs violations in the browser console without blocking anything. Switch to Enforce once the console is quiet.

Everything runs in your browser. Nothing you type or paste is sent anywhere.

Need HSTS, nosniff, Referrer-Policy and Permissions-Policy as well? Use the security headers generator and paste this policy in place of its CSP.

Policy review

No issues found by these checks.

    What a Content-Security-Policy does

    A Content-Security-Policy tells the browser which sources your page may load scripts, styles, images, frames and network connections from. If an attacker manages to inject a script tag into your page, a good policy stops the browser from running it or from sending data to the attacker's server.

    It is a second line of defence against cross-site scripting (XSS). It does not fix the bug that let the script in, and it does nothing for problems on the server such as open database rules or missing access checks.

    Check in this toolWhy it matters
    'unsafe-inline' in script-src without a nonce or hashInjected inline scripts run, which cancels most of the XSS protection
    'unsafe-eval' in script-srcStrings can be turned into code with eval() or new Function()
    * or https: or data: in script-srcScripts can load from hosts an attacker controls
    object-src not 'none'Plugin content can sidestep script rules
    Missing base-uriAn injected <base> tag can redirect your relative script URLs
    Missing frame-ancestorsOther sites can frame your page for clickjacking
    Missing default-srcEvery directive you did not list is unrestricted

    Roll it out without breaking your app

    1. 1Start with the starter policy, then add a preset for each service you use: payments, analytics, fonts, embeds, error tracking.
    2. 2Keep the Report-only toggle on and deploy to a staging copy. Report-only logs what would be blocked without blocking it.
    3. 3Open every important page, sign in, pay, upload. Read the browser console for violations and add only the origins you recognise.
    4. 4When the console is quiet, switch to Enforce. Keep watching reports for a few days after launch.

    Nonces, 'strict-dynamic' and frameworks

    The strongest policies allow scripts by nonce rather than by host: the server generates a random value for every response, adds it to the header as 'nonce-…', and puts the same value on each script tag. With 'strict-dynamic', scripts loaded by a trusted script are trusted too, and supporting browsers ignore host lists and 'unsafe-inline'.

    A nonce must be new on every response. A value hardcoded into your config gives no protection, because an attacker can read it and reuse it. Frameworks such as Next.js can generate one per request in server code; static hosts cannot, so on a static site use hashes or a host allowlist instead.

    Check what your site sends

    Read the live policy from a terminal, then paste it into Analyse mode. Only run this against a site you own.

    Terminal
    curl -sI https://your-app.example | grep -i content-security-policy

    Frequently asked questions

    Is my policy sent anywhere?

    No. Building, parsing and analysing all happen in your browser. Nothing you type or paste is sent, stored or logged.

    How is this different from the security headers generator?

    The security headers generator sets several headers at once with a simple CSP. This builder is only for Content-Security-Policy and goes deeper: every directive, service presets, report endpoints and an analyser for an existing policy.

    Why is 'unsafe-inline' allowed in style-src in the starter policy?

    Many UI libraries and frameworks inject inline styles, and blocking them breaks layouts. Inline styles carry far less risk than inline scripts. Remove it if your app works without it.

    Can I use a meta tag instead of a header?

    Partly. Browsers ignore frame-ancestors, report-uri, report-to and sandbox in a meta tag, and report-only mode is not available there. A response header is better whenever your host lets you set one.

    Does a CSP make my app secure?

    No single header does. A CSP limits the damage of script injection. Database rules, secret handling and server-side authorization matter more, and a CSP cannot fix any of them.

    Sources

    1. 1.MDN: Content Security Policy (CSP)
    2. 2.web.dev: Mitigate cross-site scripting with a strict CSP
    3. 3.OWASP Content Security Policy Cheat Sheet
    4. 4.W3C: Content Security Policy Level 3
    5. 5.Google tag platform: Use a Content Security Policy
    6. 6.Stripe: Content Security Policy for Stripe.js