CentralCSP
PoliciesContent-Security-PolicyValues

Keywords

Reference for CSP keyword sources, self, none, unsafe-inline, unsafe-eval, strict-dynamic, unsafe-hashes, report-sample, and what each one allows.

Last update:

Keyword sources are the single-quoted tokens you put in a Content Security Policy (CSP) source list, such as 'self', 'none', 'unsafe-inline', and 'strict-dynamic'. Each one switches on a specific behavior rather than naming a URL, so they decide how the browser treats inline code, dynamic script, and your own origin. The quotes are part of the token; drop them and the browser reads the word as a hostname.

A safe use, keywords carrying a strict script policy:

Content-Security-Policy: script-src 'self' 'nonce-{RANDOM}' 'strict-dynamic'

Syntax

A keyword source is a fixed token wrapped in single quotes, listed alongside any host, scheme, nonce, or hash sources in a directive value.

Content-Security-Policy:
    script-src 'self' 'strict-dynamic' 'nonce-r4nd0m';
    object-src 'none';
    base-uri 'none'

Keyword names are case-insensitive, but the quotes are required. Most keywords are only meaningful in the directives that fetch script or style; 'self' and 'none' work in any source-list directive.

What each keyword does

KeywordStatusWhat it allows
'self'✅ GoodThe page's own origin, the exact scheme, host, and port. Does not include subdomains, and does not allow inline code.
'none'✅ GoodNothing. Used alone to block every source for a directive.
'strict-dynamic'✅ GoodTrust to propagate from a nonce or hash allowed script to the scripts it loads. Turns off host and scheme allowlists.
'wasm-unsafe-eval'✅ GoodWebAssembly compilation and instantiation only, not JavaScript eval(). Widely supported across current browsers.
'report-sample'✅ GoodA short sample (the first 40 characters) of the blocked content to appear in the violation report. Reporting aid only.
'trusted-types-eval'✅ Goodeval() only when it receives a TrustedScript and Trusted Types are enforced. New; recently became available across current Chrome, Firefox, and Safari.
'unsafe-inline'❌ RiskyInline <script> and <style> blocks, javascript: URLs, and inline event handlers. Defeats the main XSS protection.
'unsafe-eval'❌ Riskyeval(), new Function(), and setTimeout/setInterval called with a string. See unsafe-eval.
'unsafe-hashes'❌ RiskyHash sources to match inline event handlers and style= attributes. Cross-browser, but re-enables the event-handler surfaces.
'inline-speculation-rules'🧪 ExperimentalInline <script type="speculationrules"> blocks. Chromium-led; not in the CSP grammar.
'report-sha256' / 'report-sha384' / 'report-sha512'🧪 ExperimentalReport-only script hash collection via csp-hash reports. Chromium-only.
'unsafe-webtransport-hashes'🧪 ExperimentalWebTransport connections matched by certificate hash. In the spec grammar; no documented browser support.
'unsafe-allow-redirects'⚠️ DeprecatedNothing in practice. A vestigial leftover of the removed navigate-to directive, with no functional definition and no browser support.

Two rules that change how keywords interact

Two interactions catch people out, because adding one keyword silently disables another.

A nonce or a hash makes 'unsafe-inline' ignored. When a script-src or style-src value contains a nonce source or a hash source, the browser drops 'unsafe-inline' from that directive. So once you add a nonce or a hash, remove 'unsafe-inline': it has no effect, and leaving it in only makes the policy harder to read. Do not rely on 'unsafe-inline' being active when a nonce is present.

Content-Security-Policy: script-src 'unsafe-inline' 'nonce-r4nd0m'

In that policy, only scripts carrying nonce="r4nd0m" run; 'unsafe-inline' has no effect.

'strict-dynamic' ignores host and scheme allowlists. When 'strict-dynamic' is present in script-src, the browser ignores every host-source and scheme-source entry (and 'unsafe-inline') in that directive. Only nonce or hash allowed scripts run, plus any scripts they create at runtime. This is what lets a strict policy avoid maintaining a host allowlist. See strict-dynamic for the full pattern.

Content-Security-Policy:
    script-src 'strict-dynamic' 'nonce-r4nd0m' https://cdn.example.com

Here https://cdn.example.com is ignored. The CDN script only loads if the nonce-allowed bootstrap script injects it.

The newer keywords

'trusted-types-eval' is the newest addition to the keyword set. It allows eval() and its relatives only when the argument is a TrustedScript, and only while Trusted Types are enforced with require-trusted-types-for. Use it instead of 'unsafe-eval' when a dependency genuinely needs eval: the string still has to pass a Trusted Types policy you wrote, so injected text cannot reach the interpreter. It recently became available across current Chrome, Firefox, and Safari, so treat it as safe but very new.

The report-only hash keywords 'report-sha256', 'report-sha384', and 'report-sha512' never allow or block anything; they ask the browser to report a hash of each script it runs. They are in the CSP3 editor's draft grammar and stable in Chromium, with no Firefox or Safari support yet.

'inline-speculation-rules' allows inline <script type="speculationrules"> blocks and nothing else. It is a Chromium-led extension that is not part of the CSP grammar (Safari has it behind a flag), so count on it only for Chromium users. 'unsafe-webtransport-hashes' sits in the spec grammar with no documented browser support, and 'unsafe-allow-redirects' is a leftover of the removed navigate-to directive with no functional definition; neither belongs in a real policy.

Insecure values to avoid

'unsafe-inline' and 'unsafe-eval' are the two values that turn off the protection CSP exists to provide. An attacker who injects markup into your page can run inline script the moment 'unsafe-inline' is in script-src, which is the exact attack a policy is meant to block. Replace 'unsafe-inline' with a nonce or a hash, and replace 'unsafe-eval' by removing the eval-style calls or by moving them behind Trusted Types with 'trusted-types-eval'. Treat 'unsafe-hashes' as a last resort for legacy inline handlers: it is standard and cross-browser, but it re-opens the event-handler attack surface a policy is meant to close, so scope it to the specific hashes you need.

What it protects against

Keywords are how a policy expresses the difference between trusting an origin and trusting arbitrary inline code. Using 'self' with a nonce and 'strict-dynamic' instead of 'unsafe-inline' blocks injected <script> blocks and inline handlers, which is the core defense against cross-site scripting (XSS). You can audit how a policy uses these keywords with the CSP evaluator.

Known limitations

The nonce-suppresses-'unsafe-inline' and 'strict-dynamic'-ignores-allowlists rules apply to script-src (and, for 'unsafe-inline', style-src); they do not change behavior in directives that never accepted inline code. 'report-sample' only adds a sample to reports and never affects whether content is blocked. 'inline-speculation-rules' and the 'report-sha...' keywords are effectively Chromium-only, so do not rely on them for behavior in Firefox or Safari. The webrtc directive takes its own pair of keywords, 'allow' and 'block', which are valid nowhere else.

Risks

Leaving 'unsafe-inline' or 'unsafe-eval' in a production script-src is the most common way a CSP ends up providing little protection. The reverse risk is adding a nonce or 'strict-dynamic' and forgetting that it disables the host allowlist you were relying on, which can break legitimate scripts until you tag them with the nonce or let 'strict-dynamic' propagate trust to them.

Examples

A strict policy that trusts inline script by nonce and lets that script load the rest:

Content-Security-Policy:
    script-src 'nonce-r4nd0m' 'strict-dynamic';
    object-src 'none';
    base-uri 'none'

A style policy that allows two specific inline styles by hash and blocks the rest:

Content-Security-Policy: style-src 'self' 'sha256-abc123...' 'sha256-def456...'

Recommendation

Build script trust on a nonce or hash plus 'strict-dynamic', and keep the unsafe-* keywords out of the policy. Set the remaining directives explicitly so nothing falls back implicitly:

Content-Security-Policy:
    default-src 'self';
    script-src 'nonce-{RANDOM}' 'strict-dynamic';
    style-src 'self';
    img-src 'self';
    font-src 'self';
    connect-src 'self';
    media-src 'self';
    manifest-src 'self';
    frame-src 'none';
    worker-src 'self';
    object-src 'none';
    base-uri 'none';
    form-action 'self';
    frame-ancestors 'none';
    upgrade-insecure-requests;
    report-to csp-endpoint
Reporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"

This is the strict CSP pattern the OWASP CSP cheat sheet and the web.dev strict CSP guide recommend: individual scripts are trusted by nonce or hash, 'strict-dynamic' lets them load what they need, and no 'unsafe-inline' or 'unsafe-eval' re-opens the injection paths the policy exists to close.

Browser support

'self', 'none', 'unsafe-inline', 'unsafe-eval', 'strict-dynamic', 'unsafe-hashes', 'report-sample', and 'wasm-unsafe-eval' are supported across current browsers. 'trusted-types-eval' is cross-browser but very recent, having just become available across current Chrome, Firefox, and Safari. 'inline-speculation-rules' and the 'report-sha...' keywords run in Chromium only, and 'unsafe-webtransport-hashes' and 'unsafe-allow-redirects' have no browser support at all.

FAQ

What does strict-dynamic do?

'strict-dynamic' lets trust propagate from a nonce or hash allowed script to the scripts it creates at runtime. When it is present in script-src, the browser ignores every host-source and scheme-source entry (and 'unsafe-inline') in that directive, so a strict policy avoids maintaining a host allowlist.

Is unsafe-inline safe if I also use a nonce?

When a script-src or style-src value contains a nonce or hash source, the browser ignores 'unsafe-inline' in that directive, so it is harmless but pointless: only nonce-matched scripts run. Leaving it in adds nothing except clutter, so remove it once you add a nonce or hash.

See also

Sources

On this page