script-src-attr
The CSP script-src-attr directive controls inline event handler attributes like onclick. See its fallback chain, values, and risks.
Last update:
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. 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:
Content-Security-Policy: script-src-attr 'none'Fallback chain
script-src-attr falls back to script-src, then to 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
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 together with the
'unsafe-hashes'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
Block all inline event handlers while letting script elements load normally:
Content-Security-Policy:
script-src 'self' 'nonce-r4nd0m';
script-src-attr 'none'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 and how script-src-elem and script-src-attr split script-src. 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 computes the digest, and the CSP evaluator flags weak handler rules.
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.'unsafe-hashes'only widens hash matching to handlers andstyle=attributes. It does not allowjavascript:URLs or whole inline<script>blocks on its own.
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
Ship the strict, nonce-based policy and make the handler ban explicit:
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 and web.dev 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
A blocked inline handler produces a csp-violation report 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
Widely supported across current browsers.