Skip to main content
Beta: Front-End Checklist is currently in beta. Some issues are still being fixed. Thanks for your patience.
JavaScriptCritical

Never use eval() or unsafe dynamic code execution

Avoid eval(), new Function(), setTimeout/setInterval with string arguments, and innerHTML with untrusted content — they execute arbitrary code and create critical XSS vulnerabilities.

Utilities
Quick take
Typical fix time 10 min
  • eval() executes arbitrary strings as code — any user input passed to it is a critical security hole
  • new Function() is equally dangerous and not caught by CSP eval restrictions
  • setTimeout('code', delay) and setInterval('code', delay) also evaluate strings — use function references instead
  • Use JSON.parse() instead of eval() for parsing JSON
Why it matters: eval() and its equivalents are the root cause of some of the most severe XSS vulnerabilities. If any user-controlled string reaches eval(), an attacker can execute arbitrary JavaScript in your users' browsers — stealing sessions, making requests as the user, or redirecting to malicious sites. Content Security Policy (CSP) blocks eval() but not new Function(), and there is never a legitimate use case that can't be solved without it.

Rule Details

eval() (opens in new tab) and similar dynamic code execution functions such as the Function() constructor (opens in new tab) run arbitrary strings as JavaScript code, creating security vulnerabilities and defeating JavaScript engine optimizations.

Code Example

// ❌ Critical: eval with user input — direct XSS
const userInput = "alert('hacked!')"
eval(userInput) // Executes arbitrary code
 
// ❌ Critical: new Function is equally dangerous
const fn = new Function('x', 'return ' + userExpression)
 
// ❌ Bad: string-based timers evaluate code
setTimeout('updateUI()', 1000) // Don't do this
setInterval('fetchData()', 5000) // Don't do this
 
// ❌ Bad: eval for JSON parsing (historically common, never safe)
const data = eval('(' + jsonString + ')')

Why It Matters

eval() and its equivalents are the root cause of some of the most severe XSS vulnerabilities. If any user-controlled string reaches eval(), an attacker can execute arbitrary JavaScript in your users' browsers — stealing sessions, making requests as the user, or redirecting to malicious sites. A strict Content Security Policy adds a browser-level backstop, but there is still no legitimate use case here that cannot be solved more safely.

Safe Alternatives

Parsing Data

// ✅ JSON.parse for JSON data
const data = JSON.parse(jsonString)
 
// ✅ URL parsing
const params = new URLSearchParams(queryString)
const value = params.get('key')

Dynamic Property Access

// ❌ Using eval for dynamic property access
const property = 'username'
const value = eval(`user.${property}`)
 
// ✅ Use bracket notation
const value = user[property]
// Add validation to ensure only expected properties are accessed
const ALLOWED = ['username', 'email', 'role']
if (ALLOWED.includes(property)) {
  const value = user[property]
}

Dynamic Dispatch

// ❌ Using eval to call a function by name
const actionName = 'save'
eval(`${actionName}Document()`)
 
// ✅ Use an explicit dispatch table
const actions = {
  save: saveDocument,
  load: loadDocument,
  export: exportDocument
}
if (actions[actionName]) {
  actions[actionName]()
}

Timers

// ❌ String-based timers
setTimeout('updateUI()', 1000)
 
// ✅ Function references
setTimeout(updateUI, 1000)
setTimeout(() => updateUI(), 1000)

ESLint Configuration

Use ESLint's no-eval rule (opens in new tab) together with no-new-func and no-implied-eval so these patterns fail in code review and CI rather than in production.

{
  "rules": {
    "no-eval": "error",
    "no-new-func": "error",
    "no-implied-eval": "error"
  }
}

Content Security Policy

Block eval at the browser level with a strict CSP:

Content-Security-Policy: script-src 'self'; object-src 'none'

Without 'unsafe-eval', eval() and new Function() will be blocked by the browser.

Exceptions

  • A framework default or browser behavior is not an exception by itself; only documented constraints with compensating controls should suppress the finding.
  • When a JavaScript pattern looks unsafe but the data is fully constrained, validated, and never attacker-controlled, document that boundary explicitly instead of treating it as implicit.
  • If a rule overlaps with a stronger exploit path or runtime failure, fix the issue that most directly enables compromise or user-visible breakage first.

Verification

Automated Checks

  • Verify the behavior in the browser after the code change, not only in static analysis.
  • Inspect DevTools Network or Performance panels when the rule affects loading or execution order.
  • Test the primary user flow and one edge case triggered by the changed script path.

Manual Checks

  • Confirm the code still behaves correctly when the feature is delayed, lazy-loaded, or fails.

Use with AI

Copy these prompts to use with your AI assistant, or install the MCP server to use directly from Claude, Cursor, or Windsurf.

Check

Verify implementation

Search this codebase for any use of eval(), new Function(), or setTimeout/setInterval with string arguments.

Fix

Auto-fix issues

Replace eval() calls with safe alternatives: JSON.parse for data, object lookups for dynamic dispatch, and Function references for timers.

Explain

Learn more

Explain why eval() is dangerous, how it enables XSS attacks, and what safe alternatives exist for each use case.

Review

Code review

Review scripts, client components, and browser execution paths related to Never use eval() or unsafe dynamic code execution. Flag exact imports, event handlers, runtime side effects, or blocking operations that violate the rule, and state how the change should be verified in the browser.

Sources

References used to support the guidance in this rule.

Further Reading

Tools and supplementary material for exploring the topic in more depth.

Rules that often go hand-in-hand with this one.

Parse JSON safely with error handling

Always wrap JSON.parse() in try/catch and validate the parsed structure before use, as invalid JSON or unexpected data shapes cause runtime errors.

JavaScript
Handle cross-origin requests securely

Use CORS correctly, validate message origins with postMessage, and understand the Same-Origin Policy to prevent cross-origin attacks.

JavaScript
Write internationalisation-friendly translation strings

Translation strings use message format patterns (ICU or similar) rather than string concatenation, and correctly handle pluralisation, gender, and variable interpolation.

JavaScript
Prefer const and let over var

Use block-scoped const and let declarations instead of function-scoped var to avoid hoisting bugs and unintended variable mutations.

JavaScript

Was this rule helpful?

Your feedback helps improve rule quality. This stays internal for now.

Loading feedback...
0 / 385