How to eliminate unsafe-eval?
csp-unsafe-eval-presentglobal
The unsafe-eval directive appears in Content Security Policy script-src declarations. It permits eval(), Function constructor, setTimeout with string arguments, and similar dynamic code execution methods. These functions convert strings into executable JavaScript at runtime. XSS attacks can exploit eval to execute injected strings as code. CSP without unsafe-eval blocks these execution vectors. Removing unsafe-eval requires refactoring code to eliminate dynamic string evaluation. The result is stricter XSS protection.
What’s wrong
The Content Security Policy script-src directive includes the unsafe-eval keyword. This permits eval(), new Function(), setTimeout with string arguments, setInterval with string arguments, and similar APIs that execute strings as code. These functions take arbitrary string input and evaluate it as JavaScript. Content Security Policy without unsafe-eval blocks these operations. The presence of unsafe-eval indicates code relies on dynamic string execution. This creates an attack surface for XSS exploitation.
Why it matters
Dynamic string evaluation creates XSS opportunities. Attackers inject malicious strings into code paths that feed eval or Function constructor. The code executes attacker-controlled JavaScript. CSP without unsafe-eval prevents this execution. Adding unsafe-eval removes the protection. Legitimate uses of eval often process configuration or template strings. If these strings include user input or data from compromised sources, eval becomes an XSS vector. The risk extends beyond direct eval calls. Libraries and framework code may use eval internally. The unsafe-eval directive permits all such usage site-wide.
The correct change
Remove unsafe-eval from the script-src directive. Identify code using eval, Function constructor, or string-based setTimeout and setInterval. Refactor eval calls to use JSON.parse for data parsing. Replace Function constructor with pre-defined function references. Convert string-based timers to function references. If template evaluation is necessary, use template engines that do not rely on eval. Migrate JavaScript-based configuration to JSON parsing. The end state is no dynamic string-to-code conversion anywhere in the codebase.
Scope
This condition applies globally. Content Security Policy affects all JavaScript execution in the page. A single unsafe-eval directive permits eval usage anywhere including third-party scripts. Pages with no direct eval calls may still depend on libraries that use eval internally. Some polyfills and legacy frameworks require eval for functionality. Globally removing unsafe-eval requires auditing first-party code, third-party libraries, and framework dependencies for eval usage. Modern framework versions often eliminate eval requirements that existed in older releases.
How to verify
- Validation confirms the condition is resolved:
- • CSP script-src directive does not contain unsafe-eval
- • No code calls eval() directly
- • No code uses new Function() to create functions from strings
- • setTimeout and setInterval use function references not strings
- • All data parsing uses JSON.parse not eval
- • Page functionality works without unsafe-eval
- • Console shows no CSP violations for blocked eval calls
Takeaway
- unsafe-eval permits eval and dynamic code execution which can be exploited for XSS
- CSP without unsafe-eval blocks string-to-code conversion entirely
- Refactoring eval calls to JSON.parse and predefined functions eliminates the need for unsafe-eval
- Third-party libraries may use eval internally requiring updates or replacement
- Modern JavaScript provides safer alternatives for all common eval use cases
FAQ
What are the legitimate uses of eval that require unsafe-eval?
Template rendering engines sometimes use eval to execute template expressions. Dynamic form validation rules stored as strings may use eval. Some configuration systems evaluate expressions in config files. Mathematical expression parsers use eval for simplicity. All these cases have safer alternatives. Template engines can use AST-based evaluation. Validation rules can use predefined function mappings. Expression parsers can build proper parsers. The convenience of eval rarely justifies the security cost.
Can eval be safely used if input is sanitized?
No. Sanitizing input before eval is extremely difficult and prone to bypass. JavaScript’s syntax complexity makes comprehensive sanitization impractical. Context-dependent meanings and encoding variations create gaps. Even minor sanitization errors enable code execution. CSP blocking eval at the platform level is more reliable than application-level sanitization. Remove eval entirely rather than attempting to sanitize inputs.
How does JSON.parse differ from eval for parsing data?
JSON.parse only parses JSON data format. It does not execute JavaScript code. eval executes any valid JavaScript including function calls and assignments. Using eval to parse JSON like eval(‘(’ + data + ‘)’) allows code execution if data contains JavaScript. JSON.parse throws an error for non-JSON input rather than executing it. This makes JSON.parse safe for untrusted input. Always use JSON.parse for parsing JSON never eval.
What if third-party libraries use eval internally?
Check for library updates. Many libraries eliminated eval in recent versions for CSP compatibility. If no eval-free version exists, evaluate alternatives. Some libraries offer CSP-compatible builds as separate packages. If replacement is not feasible, isolate the library to specific pages where unsafe-eval remains. Protect critical authentication and payment flows with strict CSP while accepting unsafe-eval on less sensitive pages. Document this as technical debt for future remediation.
Does unsafe-eval affect WebAssembly execution?
WebAssembly compilation from bytes requires wasm-eval or unsafe-eval in CSP. WebAssembly does not execute arbitrary JavaScript strings but does perform code generation. CSP Level 3 introduced wasm-unsafe-eval as a separate directive. This allows WebAssembly without permitting JavaScript eval. Use wasm-unsafe-eval if WebAssembly is needed while blocking JavaScript eval. Not all browsers support wasm-unsafe-eval yet. Check compatibility for target browsers.
What happens to setTimeout and setInterval with function arguments?
These continue working. CSP only blocks setTimeout and setInterval when passed string arguments that would be evaluated as code. Passing function references is always allowed. Replace setTimeout(‘doSomething()’, 1000) with setTimeout(doSomething, 1000) or setTimeout(() => doSomething(), 1000). The functional forms work identically but do not trigger CSP violations. Most modern code already uses function arguments making this change straightforward.
The fix
Eliminate dynamic string-to-code execution by removing unsafe-eval from Content Security Policy
Done when: CSP enforces without unsafe-eval and all dynamic code execution is refactored to safer alternatives
Do not
- Do not use eval with input sanitization as a security measure
- Do not assume unsafe-eval is necessary for JSON parsing
- Do not add unsafe-eval permanently to fix third-party library issues
- Do not use setTimeout or setInterval with string arguments
How to verify
- CSP script-src contains no unsafe-eval directive
- No eval() calls in codebase
- No Function constructor usage
- Timers use function references not strings
- Console shows no eval-related CSP violations
Find every page with this
probeo monitors this continuously across every page of your site, and records which pages passed, which failed, and which it could not determine.
Book a Call