Safeguard
Security Guides•

Why does my CSP block inline scripts and eval, and what should you do?

A CSP with script-src or default-src blocks inline scripts, event handlers and eval by default. See what unsafe-inline and unsafe-eval do and safer fixes.

Safeguard Security Team
4 min read

When a CSP includes default-src or script-src, the browser blocks inline scripts, inline event handlers, javascript: URLs and eval() unless you opt back in. Adding unsafe-inline or unsafe-eval works but removes much of the protection. Use a nonce, a hash or refactoring instead.

What is blocked by default

MDN lists the inline cases. A script element with code in the page. An inline event handler attribute such as onerror or onclick. A javascript: URL in a link. The same policy blocks eval(), the Function() constructor and the string form of setTimeout() and setInterval().

These are the usual reasons a page breaks the first time a CSP is enforced, especially one built with older templates or analytics snippets.

The two keywords

KeywordWhat it allowsMDN's guidance
'unsafe-inline'Inline scripts, handlers and javascript: URLsAvoid. It defeats much of the purpose of a CSP.
'unsafe-eval'eval and similar APIsDevelopers should avoid it, for the same reasons.

MDN notes that inline JavaScript is one of the most common XSS vectors, and that preventing its uncontrolled use is one of the basic goals of a CSP. A policy such as default-src 'self' 'unsafe-inline' therefore restricts hosts but leaves the biggest hole open.

Safer ways to keep inline code

  1. Nonce. Generate a random value on every response, put it in the policy and on each script tag you author. An injected script lacks the nonce, so it does not run.
  2. Hash. Compute a SHA-256 hash of an inline script and list it in the policy. Good for static pages, but you must recompute when the script changes.
  3. Refactor. Move code to external files, and replace inline handlers with addEventListener() calls.

A useful rule from MDN: if a directive contains nonce or hash expressions, browsers ignore unsafe-inline in it. So you can keep the keyword as a fallback for very old browsers without weakening a modern one. Unlike unsafe-inline, however, unsafe-eval still works in a directive that contains a nonce or hash.

<button id="save">Save</button>
<script nonce="PER-RESPONSE-VALUE">
  document.getElementById("save").addEventListener("click", save);
</script>

When eval is hard to remove

Some libraries use eval() or new Function() internally, for example certain template compilers. Options: switch to a build time compiled version, pick a library that does not need eval, or, when no alternative exists, consider the Trusted Types API. MDN describes a trusted-types-eval keyword that only relaxes the block in browsers where Trusted Types is enabled, so the methods stay blocked elsewhere. See Trusted Types explained.

Step by step

  1. Run the policy in report-only mode and collect violations.
  2. Sort them into inline handlers, inline scripts and eval users.
  3. Refactor handlers first, then add nonces or hashes for the inline blocks you keep.
  4. Replace or isolate eval dependencies.
  5. Enforce, and remove unsafe-inline and unsafe-eval from the policy.

For a migration walkthrough, see migrate inline scripts and handlers for a strict CSP.

Try it yourself

Open the SAST code scan demo and look at how a finding for unsafe DOM or eval use is presented with the code line and a suggested fix.

Click through it at your own pace, or open it full screen.

Quick check

Is unsafe-inline ever acceptable?

As a temporary step while migrating, with a plan to remove it. As a permanent setting, MDN says to avoid it.

Does a nonce make unsafe-inline unnecessary?

Yes. Browsers ignore unsafe-inline in a directive that has a nonce or hash, so it only serves as a fallback for browsers that do not support nonces.

Safeguard's code and dependency scanning can surface risky patterns and vulnerable libraries in pull requests. Try the free scan at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.