How to eliminate unsafe-eval?
csp-unsafe-eval-present global
The issue
A Content Security Policy that allows 'unsafe-eval' lets any script on the page turn a string into code, through eval(), new Function() or a timer given a string. If injected text reaches one of those calls, it runs. The policy is in place, but this route through it is open on every page it covers.
The cause is usually a library or an old pattern that builds code from strings, which needed 'unsafe-eval' to keep working when the policy was introduced.
Scope
The keyword applies to every script on the page, first-party and third-party alike. It is normally part of the shared policy, so it applies site-wide.
How to check you have it
- In probeo: a policy that lets scripts use
eval()is reported ascsp:script-src-unsafe-eval, graded major. - By hand: run
curl -sI https://your-site.example/ | grep -i content-security-policyand look for'unsafe-eval'inscript-src, or indefault-srcifscript-srcis absent. - In the code: search for
eval(,new Function(, andsetTimeoutorsetIntervalcalled with a string.
The fix
Remove 'unsafe-eval' from the policy after replacing the code that needs it.
Parse data with JSON.parse. Pass functions to setTimeout and setInterval, not strings. Replace generated functions with ones written ahead of time, and templates that compile to code at runtime with precompiled ones. Update or replace libraries that still evaluate strings.
Done when: the policy doesn’t allow 'unsafe-eval', the site works without it, and the check above comes back clean.
Do not
- Do not count on sanitizing input before
eval()as protection. - Do not keep
'unsafe-eval'for JSON parsing;JSON.parsedoesn’t need it. - Do not add
'unsafe-eval'permanently to suit a third-party library. - Do not pass strings to
setTimeoutorsetInterval.
FAQ
What are the legitimate uses of eval that require unsafe-eval?
Templates compiled at runtime, rules or expressions stored as strings, and older libraries. Each has an alternative: precompiled templates, a lookup of predefined functions, or a parser that doesn’t execute code.
Can eval be safely used if input is sanitized?
Not reliably. JavaScript’s syntax leaves too many ways around a filter, and one miss is enough. Removing eval() is the dependable fix.
How does JSON.parse differ from eval for parsing data?
JSON.parse only reads data and throws on anything that isn’t JSON. eval() runs whatever it is given.
What if third-party libraries use eval internally?
Check for a newer version, since many libraries removed eval() for this reason. If none exists, consider a replacement, or limit 'unsafe-eval' to the pages that load the library.
Does unsafe-eval affect WebAssembly execution?
Compiling WebAssembly is blocked without either 'unsafe-eval' or 'wasm-unsafe-eval'. Use 'wasm-unsafe-eval', which allows WebAssembly without allowing JavaScript eval().
What happens to setTimeout and setInterval with function arguments?
They keep working. Only string arguments are blocked. setTimeout(() => doSomething(), 1000) is the form to use.
Which product detects this
Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.