# Keywords (/en/docs/web-security/policies/content-security-policy/values/csp-keywords)



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:

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

## Syntax [#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.

```http
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 [#what-each-keyword-does]

| Keyword                                                                                                                                       | Status          | What it allows                                                                                                                                                                                                           |
| --------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `'self'`                                                                                                                                      | ✅ Good          | The page's own origin, the exact scheme, host, and port. Does not include subdomains, and does not allow inline code.                                                                                                    |
| `'none'`                                                                                                                                      | ✅ Good          | Nothing. Used alone to block every source for a directive.                                                                                                                                                               |
| `'strict-dynamic'`                                                                                                                            | ✅ Good          | Trust to propagate from a nonce or hash allowed script to the scripts it loads. Turns off host and scheme allowlists.                                                                                                    |
| `'wasm-unsafe-eval'`                                                                                                                          | ✅ Good          | WebAssembly compilation and instantiation only, not JavaScript `eval()`. Widely supported across current browsers.                                                                                                       |
| `'report-sample'`                                                                                                                             | ✅ Good          | A short sample (the first 40 characters) of the blocked content to appear in the violation report. Reporting aid only.                                                                                                   |
| `'trusted-types-eval'`                                                                                                                        | ✅ Good          | `eval()` only when it receives a `TrustedScript` and Trusted Types are enforced. New; recently became available across current Chrome, Firefox, and Safari.                                                              |
| `'unsafe-inline'`                                                                                                                             | ❌ Risky         | Inline `<script>` and `<style>` blocks, `javascript:` URLs, and inline event handlers. Defeats the main [XSS](/en/blog/unsafe-inline-csp) protection.                                                                    |
| `'unsafe-eval'`                                                                                                                               | ❌ Risky         | `eval()`, `new Function()`, and `setTimeout`/`setInterval` called with a string. See [unsafe-eval](/en/blog/unsafe-eval-csp).                                                                                            |
| `'unsafe-hashes'`                                                                                                                             | ❌ Risky         | Hash sources to match inline event handlers and `style=` attributes. Cross-browser, but re-enables the event-handler surfaces.                                                                                           |
| `'inline-speculation-rules'`                                                                                                                  | 🧪 Experimental | Inline `<script type="speculationrules">` blocks. Chromium-led; not in the CSP grammar.                                                                                                                                  |
| [`'report-sha256'` / `'report-sha384'` / `'report-sha512'`](/en/docs/web-security/policies/content-security-policy/values/report-sha-keyword) | 🧪 Experimental | Report-only script hash collection via `csp-hash` reports. Chromium-only.                                                                                                                                                |
| `'unsafe-webtransport-hashes'`                                                                                                                | 🧪 Experimental | WebTransport connections matched by certificate hash. In the spec grammar; no documented browser support.                                                                                                                |
| `'unsafe-allow-redirects'`                                                                                                                    | ⚠️ Deprecated   | Nothing in practice. A vestigial leftover of the removed [`navigate-to`](/en/docs/web-security/policies/content-security-policy/directives/navigate-to) directive, with no functional definition and no browser support. |

## Two rules that change how keywords interact [#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.

```http
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](/en/blog/strict-dynamic-csp) for the full pattern.

```http
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 [#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](/en/docs/web-security/policies/content-security-policy/directives/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'`](/en/docs/web-security/policies/content-security-policy/values/report-sha-keyword)
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`](/en/docs/web-security/policies/content-security-policy/directives/navigate-to)
directive with no functional definition; neither belongs in a real policy.

## Insecure values to avoid [#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](/en/docs/web-security/policies/content-security-policy/values/csp-hashes-nonce),
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 [#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](/tools/csp-evaluator).

## Known limitations [#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](/en/docs/web-security/policies/content-security-policy/directives/webrtc)
takes its own pair of keywords, `'allow'` and `'block'`, which are valid nowhere
else.

## Risks [#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 [#examples]

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

```http
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:

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

## Recommendation [#recommendation]

Build script trust on a
[nonce or hash](/en/docs/web-security/policies/content-security-policy/values/csp-hashes-nonce)
plus `'strict-dynamic'`, and keep the `unsafe-*` keywords out of the policy. Set
the remaining directives explicitly so nothing falls back implicitly:

```http
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
```

```http
Reporting-Endpoints: csp-endpoint="https://<Endpoint-ID>.report.centralcsp.com"
```

This is the strict CSP pattern the
[OWASP CSP cheat sheet](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html)
and the [web.dev strict CSP guide](https://web.dev/articles/strict-csp)
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 [#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 [#faq]

### What does strict-dynamic do? [#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? [#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 [#see-also]

* [script-src directive](/en/docs/web-security/policies/content-security-policy/directives/script-src)
* [style-src directive](/en/docs/web-security/policies/content-security-policy/directives/style-src)
* [Host source](/en/docs/web-security/policies/content-security-policy/values/csp-host-source)
* [Hashes and nonces](/en/docs/web-security/policies/content-security-policy/values/csp-hashes-nonce)
* [report-sha256 keyword](/en/docs/web-security/policies/content-security-policy/values/report-sha-keyword)
* [How to remove unsafe-inline](/en/blog/unsafe-inline-csp)
* [Replacing unsafe-eval](/en/blog/unsafe-eval-csp)
* [Building a strict policy with strict-dynamic](/en/blog/strict-dynamic-csp)

## Sources [#sources]

* [W3C, Content Security Policy Level 3, source lists](https://w3c.github.io/webappsec-csp/#framework-directive-source-list)
* [MDN, CSP source values](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy)
* [web.dev, Mitigate XSS with a strict CSP](https://web.dev/articles/strict-csp)
* [OWASP, Content Security Policy cheat sheet](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html)
