tezvyn:

XSS Prevention: Context-Aware Output Encoding

AI-drafted, machine-checkedSource: cheatsheetseries.owasp.orgbeginner

Prevent XSS by encoding all untrusted data just before it's rendered. The key is context: escaping for an HTML body is different from an attribute or script tag. This is critical for displaying user content.

WHY IT EXISTS: Cross-Site Scripting (XSS) happens because browsers cannot distinguish between your site's legitimate code and malicious scripts injected via user input. When your server renders user data (like a comment) directly into HTML without escaping it, the browser executes any embedded scripts as if they came from you, giving them full access to the user's session data.

THE MENTAL MODEL: Think of user input as a package you must wrap before delivering it to the browser. The wrapping (encoding) depends on the destination. A package for the HTML body needs one type of wrapping, while a package for a JavaScript variable inside a <script> tag needs another. Never pass the raw, unwrapped package directly to the browser.

HOW IT WORKS: The core principle is to encode all untrusted data on output, right before it's inserted into the document. This process, called output encoding or escaping, converts special characters into their safe, non-executable equivalents. For example, in an HTML context, < becomes <. This tells the browser to display the characters as text, not to interpret them as HTML tags. Different contexts require different encoding rules. Data inside a JavaScript string needs to be escaped for JavaScript, while data in a URL parameter needs URL encoding.

WHEN TO USE IT: Always apply output encoding when rendering any data that originated from an external source, especially user input. This includes data from databases that store user content, URL parameters, or data from third-party APIs. It's critical for features like comment sections, user profiles, and search result pages. Most modern templating engines (like EJS or Pug in Node.js) do this automatically for HTML contexts, but you must be careful when manually inserting data into other contexts like scripts or CSS.

WHEN NOT TO USE IT: Do not encode data that is meant to be interpreted as HTML, such as content from a trusted CMS where an administrator is intentionally writing HTML. In these rare cases, use HTML sanitization instead. Sanitization parses the HTML and removes dangerous tags (like <script>) and attributes (like onclick), while allowing a safe subset. Also, avoid double-encoding data, as it can lead to broken rendering.

ONE CANONICAL EXAMPLE: A user submits a comment: <script>alert('XSS')</script>. If you render this directly, every user who views it will see a JavaScript alert. The correct approach is to encode it for the HTML context. In a Node.js EJS template, using <%= comment %> (escaped by default) instead of <%- comment %> (unescaped) sends <script>alert('XSS')</script> to the browser. The browser then displays the literal text of the tag, preventing script execution.

Read the original → cheatsheetseries.owasp.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.