Cross-site scripting (XSS) from template variable in JavaScript context in HTML template

High Risk Application Security
xsshtml-templatesjavascripttemplate-injectioncross-site-scripting

What it is

Embedding template variables directly into JavaScript code within HTML templates creates a cross-site scripting (XSS) vulnerability. HTML escaping is insufficient for JavaScript contexts, allowing attackers to inject malicious scripts through user-controlled data. This can lead to session hijacking, data theft, unauthorized actions, and complete compromise of the user's browser session.

â„šī¸ Configuration Fix

Configuration changes required - see explanation below.

💡 Explanation

â„šī¸ Configuration Fix

Configuration changes required - see explanation below.

💡 Explanation

â„šī¸ Configuration Fix

Configuration changes required - see explanation below.

💡 Explanation

Why it happens

Template variables like {{ user.name }} or <%= value %> embedded directly into JavaScript code within <script> tags. HTML escaping is applied when JavaScript-specific encoding is required, allowing attackers to break out of strings and inject malicious code through quotes, newlines, or script tags.

Root causes

Direct Template Variable Embedding in Script Tags

Template variables like {{ user.name }} or <%= value %> embedded directly into JavaScript code within <script> tags. HTML escaping is applied when JavaScript-specific encoding is required, allowing attackers to break out of strings and inject malicious code through quotes, newlines, or script tags.

HTML Escaping in JavaScript Contexts

Template engines apply HTML entity encoding (&lt;, &gt;, &quot;) to variables in JavaScript contexts where JavaScript string escaping is needed. HTML escaping doesn't prevent breaking out of JavaScript strings with characters like apostrophes, backslashes, or newlines.

Insufficient Context-Aware Encoding Knowledge

Developers lack understanding that different output contexts (HTML body, HTML attributes, JavaScript, CSS, URLs) require different encoding strategies. They apply a single escaping method everywhere, leaving JavaScript contexts vulnerable to injection.

Template Engine JavaScript Context Gaps

Template engines have insufficient default protections specifically for JavaScript contexts. Auto-escaping features designed for HTML don't properly encode for JavaScript string contexts, requiring explicit JavaScript encoding functions that developers often overlook.

Server-Side and Client-Side Data Mixing

Server-side template data mixed directly with client-side JavaScript code creates complex parsing and encoding challenges. Developers embed dynamic server values into JavaScript variables, event handlers, or inline scripts without proper isolation or encoding.

Fixes

1

Use JSON Serialization for Data Transfer

Serialize server-side data to JSON and embed it as a data structure rather than directly into JavaScript strings. Use template filters like |tojson (Jinja2), json_encode() (PHP), or JSON.stringify (Node.js) to safely convert data to JSON format that JavaScript can parse without code execution.

2

Apply JavaScript-Specific Encoding

Use JavaScript context-aware encoding functions like OWASP ESAPI's encodeForJavaScript(), or framework-specific filters that properly escape quotes, backslashes, newlines, and other JavaScript special characters. Never use HTML entity encoding for JavaScript contexts.

3

Leverage Framework-Specific Safe Features

Use template framework features specifically designed for JavaScript contexts like Django's json_script filter, which safely embeds JSON data in script tags with proper encoding. These features handle context-aware encoding automatically and securely.

4

Separate Data from Code Using Data Attributes

Store server-side data in HTML data attributes (data-*) or hidden form fields, then access them from JavaScript using DOM APIs. This completely separates data from code execution contexts, eliminating the possibility of code injection through data values.

5

Implement Content Security Policy

Deploy strict Content Security Policy headers that disable inline scripts (script-src 'self'; no 'unsafe-inline') and require nonces or hashes for necessary inline scripts. CSP provides defense-in-depth by blocking XSS exploitation even if injection occurs.

6

Enable Context-Aware Auto-Escaping

Configure template engines to use context-aware auto-escaping that applies appropriate encoding based on output context (HTML, JavaScript, CSS, URL). Review template engine documentation for JavaScript context escaping options and enable them globally.

7

Validate and Sanitize User Input

Implement comprehensive input validation and sanitization before storing user data. While output encoding is essential, input validation provides an additional security layer by rejecting obviously malicious content before it reaches templates.

Detect This Vulnerability in Your Code

Sourcery automatically identifies cross-site scripting (xss) from template variable in javascript context in html template and many other security issues in your codebase.