# script-src-attr (/en/docs/web-security/policies/content-security-policy/directives/script-src-attr)



The `script-src-attr` directive in a Content Security Policy (CSP) controls inline event handler attributes, the JavaScript written directly in HTML attributes such as `onclick`, `onload`, and `onmouseover`. It does not cover `<script>` elements, those belong to [`script-src-elem`](/en/docs/web-security/policies/content-security-policy/directives/script-src-elem). Use `script-src-attr` to apply a separate, usually stricter, rule to inline handlers.

A minimal safe policy for this directive, blocking every inline handler:

```http
Content-Security-Policy: script-src-attr 'none'
```

## Fallback chain [#fallback-chain]

`script-src-attr` falls back to [`script-src`](/en/docs/web-security/policies/content-security-policy/directives/script-src), then to [`default-src`](/en/docs/web-security/policies/content-security-policy/directives/default-src). If you do not set `script-src-attr`, inline handlers are checked against `script-src`, and if that is absent, against `default-src`. Setting `script-src-attr` replaces `script-src` for handler attributes only.

Most policies do not need `script-src-attr` because `script-src` already covers handlers. The common reason to set it is to forbid all inline handlers outright with `'none'` while still allowing script elements through `script-src`.

## Values [#values]

`script-src-attr` takes the same value kinds as `script-src`, but only a few of them can match an inline handler.

| Value             | Status  | Description                                                                             |
| ----------------- | ------- | --------------------------------------------------------------------------------------- |
| `'none'`          | ✅ Good  | Blocks every inline event handler. Used alone.                                          |
| `'sha256-...'`    | ✅ Good  | Digest of the exact handler text; matches only together with `'unsafe-hashes'`.         |
| `'unsafe-hashes'` | ❌ Risky | Lets hashes match handler attributes; re-enables that surface, use as a migration step. |
| `'report-sample'` | ✅ Good  | Adds the first 40 characters of the blocked handler to reports.                         |
| `'unsafe-inline'` | ❌ Risky | Allows every inline handler, including injected ones.                                   |

The grammar also accepts `'self'`, host, scheme, and nonce sources, but an inline handler has no URL for them to match. In practice `script-src-attr` is used with a small set of values:

* `'none'` to block every inline event handler.
* `'unsafe-inline'` to allow them all (discouraged).
* A [hash](/en/docs/web-security/policies/content-security-policy/values/csp-hashes-nonce) together with the [`'unsafe-hashes'`](/en/docs/web-security/policies/content-security-policy/values/csp-keywords) keyword, which is what lets a hash match an inline handler.

A nonce cannot tag an attribute, so handlers are allowed by `'unsafe-inline'` or by a hash plus `'unsafe-hashes'`, not by a nonce.

## Examples [#examples]

Block all inline event handlers while letting script elements load normally:

```http
Content-Security-Policy:
    script-src 'self' 'nonce-r4nd0m';
    script-src-attr 'none'
```

## Common use [#common-use]

The cleanest setup is `script-src-attr 'none'`, which forces all behavior into nonce-tagged script files and matches the strict CSP pattern, see the [strict-dynamic guide](/en/blog/strict-dynamic-csp) and [how script-src-elem and script-src-attr split script-src](/en/blog/script-src-elem-vs-script-src-attr). If you cannot remove a legacy handler immediately, hash it and add `'unsafe-hashes'`, then plan to migrate the handler into a script file. The [hash generator](/tools/csp-hash) computes the digest, and the [CSP evaluator](/tools/csp-evaluator) flags weak handler rules.

## Security notes [#security-notes]

Inline event handlers are a frequent XSS sink, an injected `onclick` runs code in the page context. `script-src-attr 'none'` removes that sink entirely.

* `'unsafe-inline'` allows every handler, including injected ones, so it undoes the protection. See [why to drop unsafe-inline](/en/blog/unsafe-inline-csp).
* `'unsafe-hashes'` only widens hash matching to handlers and `style=` attributes. It does not allow `javascript:` URLs or whole inline `<script>` blocks on its own.

## Known bypasses and risks [#known-bypasses-and-risks]

The main risk is leaving handlers open by accident. If `script-src-attr` is unset and `script-src` (or `default-src`) carries `'unsafe-inline'`, every inline handler runs, even with a tight rule on script elements. Set `script-src-attr 'none'` to close that gap.

`'unsafe-hashes'` is a controlled relaxation, but each hashed handler is a fixed string. Any change to the handler text breaks the hash, and the temptation is to fall back to `'unsafe-inline'`, which reopens the sink. Treat hashed handlers as a migration step, not a destination.

## Recommendation [#recommendation]

Ship the strict, nonce-based policy and make the handler ban explicit:

```http
Content-Security-Policy:
    script-src 'nonce-{RANDOM}' 'strict-dynamic';
    script-src-attr 'none';
    object-src 'none';
    base-uri 'none'
```

The strict CSP that the [OWASP CSP cheat sheet](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html) and [web.dev](https://web.dev/articles/strict-csp) recommend already blocks inline handlers, since nothing in it allows them. Adding `script-src-attr 'none'` states that intent directly and keeps handlers blocked even if `script-src` is relaxed later. Move handler code into nonce-tagged script files.

## Reporting [#reporting]

A blocked inline handler produces a [csp-violation report](/en/docs/web-security/reporting-api/reports/csp-violation) with `script-src-attr` as the effective directive. Add `'report-sample'` to include a short sample of the handler so you can locate it. CentralCSP aggregates these reports so you can find and remove inline handlers before tightening the directive.

## Browser support [#browser-support]

Widely supported across current browsers.

## See also [#see-also]

* [script-src](/en/docs/web-security/policies/content-security-policy/directives/script-src)
* [script-src-elem](/en/docs/web-security/policies/content-security-policy/directives/script-src-elem)
* [default-src](/en/docs/web-security/policies/content-security-policy/directives/default-src)
* [CSP keyword values](/en/docs/web-security/policies/content-security-policy/values/csp-keywords)
* [Hash generator](/tools/csp-hash)

## Sources [#sources]

* [MDN, CSP script-src-attr](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src-attr)
* [W3C, Content Security Policy Level 3](https://www.w3.org/TR/CSP3/)
* [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)
