CentralCSP
PoliciesContent-Security-PolicyDirectives

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.

ValueStatusDescription
'none'✅ GoodBlocks every inline event handler. Used alone.
'sha256-...'✅ GoodDigest of the exact handler text; matches only together with 'unsafe-hashes'.
'unsafe-hashes'❌ RiskyLets hashes match handler attributes; re-enables that surface, use as a migration step.
'report-sample'✅ GoodAdds the first 40 characters of the blocked handler to reports.
'unsafe-inline'❌ RiskyAllows 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 and style= attributes. It does not allow javascript: 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.

See also

Sources

On this page