{
    "source": "https://csp.fail/api/directives.json",
    "about": "Content Security Policy directives: what each governs, whether it inherits from default-src, the recommended value, and the usual mistake.",
    "licence": "CC BY 4.0",
    "attribution": "CSP Fail",
    "directives": [
        {
            "name": "default-src",
            "governs": "The fallback for every fetch directive that is not set explicitly.",
            "inheritsFromDefaultSrc": null,
            "recommended": "default-src 'self'",
            "commonMistake": "Assuming it covers every directive. It is a fallback for fetch directives only."
        },
        {
            "name": "script-src",
            "governs": "Where scripts may load from, and whether inline script and eval are permitted.",
            "inheritsFromDefaultSrc": true,
            "recommended": "script-src 'nonce-{RANDOM}' 'strict-dynamic'",
            "commonMistake": "Listing hosts. An allowlist promises an origin, not its content: a JSONP endpoint, a framework gadget or a user-upload host on any listed origin defeats it."
        },
        {
            "name": "script-src-elem",
            "governs": "Script elements specifically. Inherits from script-src when unset.",
            "inheritsFromDefaultSrc": true,
            "recommended": "Usually unnecessary; set script-src instead.",
            "commonMistake": "Being surprised to see it named in violation reports when you only set script-src."
        },
        {
            "name": "script-src-attr",
            "governs": "Inline event handler attributes such as onclick.",
            "inheritsFromDefaultSrc": true,
            "recommended": "script-src-attr 'none'",
            "commonMistake": "Forgetting that inline handlers are governed separately from script elements."
        },
        {
            "name": "style-src",
            "governs": "Where stylesheets may load from and whether inline styles are permitted.",
            "inheritsFromDefaultSrc": true,
            "recommended": "style-src 'self'",
            "commonMistake": "Treating 'unsafe-inline' as harmless here. CSS attribute selectors can exfiltrate data character by character."
        },
        {
            "name": "img-src",
            "governs": "Where images may load from, including favicons.",
            "inheritsFromDefaultSrc": true,
            "recommended": "img-src 'self'",
            "commonMistake": "Setting * because images feel harmless. An image URL is an outbound request an attacker can put data into."
        },
        {
            "name": "connect-src",
            "governs": "fetch, XHR, WebSocket, EventSource and sendBeacon destinations.",
            "inheritsFromDefaultSrc": true,
            "recommended": "connect-src 'self'",
            "commonMistake": "Allowlisting a third-party analytics host, which then serves as an exfiltration destination for anyone who achieves script execution."
        },
        {
            "name": "font-src",
            "governs": "Where fonts may load from.",
            "inheritsFromDefaultSrc": true,
            "recommended": "font-src 'self'",
            "commonMistake": "Allowing a third-party font CDN on a site that otherwise loads nothing cross-origin."
        },
        {
            "name": "object-src",
            "governs": "The <object>, <embed> and <applet> elements.",
            "inheritsFromDefaultSrc": true,
            "recommended": "object-src 'none'",
            "commonMistake": "Leaving it to inherit. It did not inherit in CSP1 or CSP2, and there is essentially no site that needs it."
        },
        {
            "name": "frame-src",
            "governs": "What may be loaded into frames on your page.",
            "inheritsFromDefaultSrc": true,
            "recommended": "frame-src 'none' unless you embed third parties",
            "commonMistake": "Confusing it with frame-ancestors, which is the opposite direction."
        },
        {
            "name": "worker-src",
            "governs": "Web workers, shared workers and service workers.",
            "inheritsFromDefaultSrc": true,
            "recommended": "worker-src 'self'",
            "commonMistake": "Overlooking it: a service worker registered by an attacker outlives the page that registered it."
        },
        {
            "name": "base-uri",
            "governs": "What the <base> element may set as the document base URL.",
            "inheritsFromDefaultSrc": false,
            "recommended": "base-uri 'none'",
            "commonMistake": "Leaving it unset, because default-src does not cover it. An injected <base href> rebases every relative URL, including your own nonced script tags."
        },
        {
            "name": "form-action",
            "governs": "Where forms may submit, including via a button formaction attribute.",
            "inheritsFromDefaultSrc": false,
            "recommended": "form-action 'self'",
            "commonMistake": "Assuming a script directive covers it. A formaction override is neither script nor navigation."
        },
        {
            "name": "frame-ancestors",
            "governs": "Which origins may frame this page. Supersedes X-Frame-Options.",
            "inheritsFromDefaultSrc": false,
            "recommended": "frame-ancestors 'none'",
            "commonMistake": "Delivering it in a <meta> tag, where it is silently ignored."
        },
        {
            "name": "report-uri",
            "governs": "Where violation reports are POSTed. Deprecated but universally supported.",
            "inheritsFromDefaultSrc": false,
            "recommended": "report-uri https://your-endpoint",
            "commonMistake": "Omitting it, which leaves you unable to see what the policy blocks in the wild."
        },
        {
            "name": "report-to",
            "governs": "The reporting group that receives violations. The modern replacement for report-uri.",
            "inheritsFromDefaultSrc": false,
            "recommended": "report-to default, alongside report-uri and a Reporting-Endpoints header",
            "commonMistake": "Setting it without a Reporting-Endpoints header defining the named group."
        },
        {
            "name": "upgrade-insecure-requests",
            "governs": "Rewrites http:// subresource requests to https:// before they are made.",
            "inheritsFromDefaultSrc": false,
            "recommended": "upgrade-insecure-requests",
            "commonMistake": "Treating it as a substitute for fixing mixed content at source."
        },
        {
            "name": "sandbox",
            "governs": "Applies iframe-style sandboxing to the document itself.",
            "inheritsFromDefaultSrc": false,
            "recommended": "Leave unset unless you know you want it.",
            "commonMistake": "Adding it speculatively: it can strip the origin and break the page in ways that are hard to trace."
        }
    ]
}