// SECURITY / LIQUID_SECURITY_DOCS

// LIQUID_SECURITY_DOCS

Security vulnerabilities in Shopify themes can expose customer data, enable account takeovers, and compromise entire storefronts. This guide covers every attack vector.

[ 01 ] SECURITY OVERVIEW

Shopify themes execute in a privileged context: they have access to customer session data, cart tokens, and payment flows. A single XSS vulnerability can lead to complete account compromise.

Unlike traditional web apps, Liquid templates are server-rendered — but they frequently inject data into JavaScript contexts, creating dangerous mixing of trusted and untrusted data.

// HIGH RISK PATTERNS

  • Unescaped Liquid variables in JavaScript contexts
  • innerHTML assignment with user-controlled data
  • cart.token exposure in front-end code
  • eval() with dynamic string construction
  • document.write() with external data

[ 02 ] XSS IN SHOPIFY THEMES

innerHTML Vulnerabilities

VULNERABLE — innerHTML with Liquid data
// DANGEROUS: Liquid value injected directly into innerHTML
document.getElementById('product-title').innerHTML = "{{ product.title }}";

// If product.title = '<img src=x onerror=alert(1)>'
// This executes arbitrary JavaScript
SECURE — Use textContent or escape
// SAFE: textContent never executes HTML
document.getElementById('product-title').textContent = "{{ product.title | escape }}";

// Or use the escape filter in Liquid before injection
const title = {{ product.title | json }};
element.textContent = title;

Unescaped Output

VULNERABLE — Raw output in JS
<script>
  var metafield = "{{ product.metafields.custom.description }}";
</script>
SECURE — JSON-encoded output
<script>
  var metafield = {{ product.metafields.custom.description | json }};
</script>

[ 03 ] CSRF VULNERABILITIES

Shopify provides CSRF protection via form tokens, but custom implementations often bypass this protection.

SECURE — Always include form token
{% form 'customer' %}
  {{ form.errors | default_errors }}
  <input type="email" name="customer[email]" required>
  <button type="submit">Subscribe</button>
{% endform %}
{# form tag automatically includes authenticity_token #}
SECURE — Include token in AJAX cart requests
// Include Shopify's CSRF token in fetch requests
const response = await fetch('/cart/add.js', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Requested-With': 'XMLHttpRequest'
  },
  body: JSON.stringify({ id: variantId, quantity: 1 })
});

[ 04 ] SENSITIVE DATA EXPOSURE

cart.token Risks

The cart.token is a session identifier. Exposing it in front-end JavaScript allows session hijacking.

VULNERABLE — cart.token in JavaScript
<script>
  // NEVER expose cart.token to JavaScript
  var cartToken = "{{ cart.token }}";
  analytics.track('cart_view', { token: cartToken });
</script>
SECURE — Use cart API without token
<script>
  // Use cart API endpoint instead — token is managed server-side
  fetch('/cart.js')
    .then(r => r.json())
    .then(cart => analytics.track('cart_view', { items: cart.item_count }));
</script>

[ 05 ] eval() AND DYNAMIC CODE

eval(), new Function(), and setTimeout(string) execute arbitrary code. Combined with Liquid injection, they create critical RCE-equivalent vulnerabilities in the browser.

VULNERABLE — eval with Liquid data
// CRITICAL: eval() with user-controlled data
var action = "{{ request.path }}";
eval('router.' + action + '()');

// EVAL ALTERNATIVES

  • Use object property lookup instead: obj[action]
  • Use switch/case for known values
  • Use JSON.parse() for data — never eval()
  • CSP can block eval() at browser level

[ 06 ] SECURE CODING CHECKLIST

Always escape Liquid output with | escape or | json in JS contexts

REQUIRED

Never expose cart.token or customer session data to JavaScript

REQUIRED

Use {% form %} tags — never raw HTML forms for Shopify actions

REQUIRED

Avoid innerHTML — use textContent or DOM methods

REQUIRED

Never use eval(), new Function(), or setTimeout(string)

REQUIRED

Validate all URL parameters before using in page logic

REQUIRED

Implement Content Security Policy headers

RECOMMENDED

Audit third-party scripts for data collection patterns

RECOMMENDED

Use Syphio to automate security rule enforcement

RECOMMENDED

// SEE ALSO

// SYPHIO SCANS ALL OF THIS AUTOMATICALLY

84 security rules. Zero configuration required.

SCAN_YOUR_CODE