eval() in a Shopify Theme Is a Critical XSS Vulnerability — Here's What to Use Instead
eval() executes any JavaScript string as code. If an attacker can influence the string passed to eval() — through a product title, a metafield, a URL parameter, or any other user-controlled value — they can execute arbitrary JavaScript in every visitor's browser. This includes stealing session cookies, capturing payment form keystrokes, and silently modifying orders. eval() has no legitimate use case in a Shopify theme that cannot be replaced with a safer pattern. This guide covers every common use and its secure replacement.
Why eval() is uniquely dangerous in Shopify themes
Shopify themes process data from multiple sources that attackers can influence: product titles and descriptions (settable via bulk import and apps), metafield values (sometimes exposed via customer-facing apps), URL query parameters, and cart item properties. Any of these values reaching eval() represents immediate critical XSS. Additionally, eval() prevents JavaScript minification and tree-shaking, triggers Content Security Policy violations, and is disabled in strict mode. There is no defensive use of eval() in theme code.
eval() for JSON parsing — use JSON.parse() instead
The most common legitimate-looking use of eval() in older Shopify themes is parsing JSON from a script tag or AJAX response: eval('(' + jsonString + ')'). This was a pre-ES5 workaround. The correct replacement is JSON.parse(jsonString). JSON.parse() only accepts valid JSON (no executable JavaScript), throws a SyntaxError for invalid input, and is 10-100x faster than eval(). If the JSON string might be malformed, wrap it in try/catch: try { const data = JSON.parse(str); } catch(e) { console.error('Invalid JSON:', e); }.
eval() for dynamic function calls — use a dispatch table instead
Another eval() misuse in themes: dynamically calling a function by name received from HTML data attributes. Instead of eval(element.dataset.action + '()'), build a dispatch table: const actions = { openModal: () => modal.open(), closeModal: () => modal.close(), addToCart: () => cart.add() }; const action = actions[element.dataset.action]; if (typeof action === 'function') action();. This allows only the specific functions in the table to be called — not arbitrary code execution.
Finding eval() in your theme and related patterns
Search your theme JavaScript for: eval(, new Function(, setTimeout('string', and setInterval('string'. All four execute string arguments as code and are equally dangerous. new Function('code')() is functionally identical to eval(). setTimeout and setInterval with string first arguments (rather than function references) also invoke eval internally. All of these must be replaced. Theme Check and Syphio both flag eval() and new Function() as CRITICAL security issues.
The fix: before and after
// CODE_COMPARISON
Frequently asked questions
- What is the Content Security Policy implication of using eval()?
A Content Security Policy with script-src 'self' (or any policy without 'unsafe-eval') blocks all eval() calls, causing JavaScript errors. If you are implementing CSP on your Shopify theme — which is a security best practice — eval() in your theme will break your own functionality. Removing eval() is a prerequisite for effective CSP implementation.
- Is JSON.parse() completely safe for all inputs?
JSON.parse() is safe against code injection — it only parses valid JSON structures and does not execute JavaScript. It will throw a SyntaxError for non-JSON input, which you should catch. The output is always a plain JavaScript data structure (object, array, string, number, boolean, null) — never executable code. Always wrap JSON.parse() in try/catch when parsing data from potentially unreliable sources.
- Does Shopify's CSP prevent eval() by default?
As of 2025, Shopify does not enforce a Content Security Policy on all storefronts by default. However, browser vendors are increasingly restrictive about eval() in secure contexts, and Shopify has indicated CSP support is being expanded. Building themes without eval() now ensures compatibility with future CSP enforcement and is a security best practice regardless.
// SCAN_YOUR_CODE
Does your theme have this bug?
Paste your code. Syphio automatically detects and fixes this error and hundreds of others — in seconds.
Audit my theme →