Skip to content
script-src.com
script-src.com
EN / FR

unsafe-inline, unsafe-eval, and friends

What the unsafe-inline, unsafe-eval, unsafe-hashes, and wasm-unsafe-eval keywords allow in script-src, and when each is justified.

The unsafe- keywords each relax script-src in a specific way. They exist for compatibility with code you cannot immediately change. Treat every one as a temporary allowance to remove, not a default.

'unsafe-inline'

Allows all inline scripts, inline event handler attributes, and javascript: URLs:

script-src 'unsafe-inline'

This effectively disables the XSS protection script-src provides, because an injected inline script is now indistinguishable from a legitimate one. Prefer a nonce or a hash instead. As noted on those pages, a nonce or hash in the same directive causes browsers to ignore 'unsafe-inline', so you can list it purely as an old-browser fallback.

'unsafe-eval'

Allows string-to-code APIs:

script-src 'unsafe-eval'

This covers eval(), new Function(), and setTimeout / setInterval when called with a string argument. Some older template engines and libraries need it. Modern equivalents usually do not. Removing 'unsafe-eval' is often just a matter of upgrading a dependency or passing a function instead of a string to setTimeout.

'wasm-unsafe-eval'

Allows compiling and instantiating WebAssembly without allowing JavaScript eval:

script-src 'wasm-unsafe-eval'

Before this keyword existed, running WebAssembly required the much broader 'unsafe-eval'. If you only need Wasm, use 'wasm-unsafe-eval' so JavaScript eval stays blocked.

'unsafe-hashes'

Allows specific inline event handlers whose code matches a listed hash:

script-src 'unsafe-hashes' 'sha256-hashOfHandlerCode'

A normal script hash does not cover attribute handlers like onclick="doThing()", because the hash is computed over script element content, not attributes. 'unsafe-hashes' extends hashing to those handlers. It is weaker than moving the handler into a hashed or nonced <script> block, so use it only when you cannot edit the markup.

Removing them

A practical order to tighten a policy:

  1. Replace 'unsafe-inline' with nonces or hashes.
  2. Swap 'unsafe-eval' for 'wasm-unsafe-eval' if only Wasm needs it, then remove it entirely once dependencies allow.
  3. Move inline onclick handlers into scripts and drop 'unsafe-hashes'.

Watch your violation reports while doing this, so you catch anything that breaks before users do.