Encoders

HTML Encoder/Decoder

Encode special characters to HTML entities or decode HTML entities back to text.

Advertisement

Why HTML Encoding Matters

HTML encoding is the process of converting characters that have special meaning in HTML — such as `<`, `>`, `&`, and `"` — into their corresponding HTML entities (`&lt;`, `&gt;`, `&amp;`, `&quot;`). This conversion is essential whenever untrusted or user-supplied data is inserted into an HTML document, because without it the browser may interpret the data as HTML markup rather than display text.

The most critical reason to encode is to prevent cross-site scripting (XSS) attacks. If an attacker can inject `<script>` tags or event-handler attributes into a page viewed by other users, they can execute arbitrary JavaScript in those users' sessions, stealing cookies, making unauthorized requests, or modifying page content. XSS is one of the most common and damaging web vulnerabilities, and proper encoding is the primary defense against it.

Beyond security, encoding also prevents rendering bugs. A user's bio containing the text "5 < 3 but 7 > 2" will display incorrectly without encoding, because the browser interprets `<` as the start of a tag. Encoding ensures that text is rendered exactly as intended, regardless of which characters it contains.

  • Prevents XSS by neutralizing characters that have HTML meaning
  • Ensures text is rendered exactly as intended, not interpreted as markup
  • Required whenever untrusted data is inserted into HTML
  • A primary defense layer in any web application security strategy

Understanding HTML Entities

HTML entities are special sequences that represent characters. They begin with an ampersand (`&`) and end with a semicolon (`;`). Named entities like `&lt;`, `&gt;`, `&amp;`, `&quot;`, and `&apos;` represent the five characters most relevant to security. Numeric entities like `&#60;` (decimal) and `&#x3C;` (hexadecimal) can represent any Unicode code point.

The five characters that must be encoded in security-critical contexts are: `&` (must be encoded first to avoid double-encoding issues), `<` and `>` (to prevent tag injection), `"` (to prevent breaking out of attribute values), and `'` (to prevent breaking out of single-quoted attribute values). Encoding these five characters is sufficient to prevent XSS in the vast majority of cases, when applied in the correct context.

Named entities also exist for a wide range of symbols, mathematical operators, currency signs, and emojis (`&copy;`, `&mdash;`, `&euro;`, `&hearts;`). These are useful for including special characters in HTML without relying on the document's character encoding, but they are not security-relevant in the way the five core entities are.

  • Named entities: &lt; &gt; &amp; &quot; &apos;
  • Numeric entities: &#60; (decimal) or &#x3C; (hexadecimal)
  • Encode & first to avoid double-encoding issues
  • Encoding the five core entities prevents XSS in most contexts

Context Matters: Encoding for Different Locations

HTML encoding is not a single operation; the correct encoding depends on where in the HTML document the data is being inserted. Different contexts have different escaping requirements, and using the wrong encoding for a context can leave an XSS vulnerability even when encoding is applied.

In HTML text content (between tags), encoding `<`, `>`, and `&` is sufficient. In attribute values, you must also encode the quote character used to delimit the attribute (typically `"` for double-quoted attributes). In single-quoted attributes, encode `'` instead. In URL attributes like `href` and `src`, you must URL-encode the value in addition to HTML-encoding it, and you must validate the URL scheme to prevent `javascript:` URLs.

The most dangerous contexts are those that switch to a different parsing mode. Inside `<script>` tags, HTML encoding does not apply at all — the content is parsed as JavaScript, and you must use JavaScript-specific escaping. Inside event handler attributes (`onclick`, `onload`), the value is parsed as JavaScript after HTML decoding, so HTML encoding alone is not sufficient. Inside `<style>` tags, the content is parsed as CSS. For these contexts, avoid inserting untrusted data entirely, or use a dedicated, context-aware escaping library.

  • Text content: encode <, >, &
  • Attribute values: also encode the delimiting quote character
  • URL attributes: URL-encode plus HTML-encode, and validate the scheme
  • Script and style contexts: avoid untrusted data or use specialized escaping

Decoding HTML Entities

HTML decoding reverses the encoding process, converting entities back to their original characters. This is needed when processing HTML content programmatically — for example, when extracting text from a scraped web page, parsing an RSS feed, or displaying content that was encoded for safe transport. The browser decodes entities automatically when rendering, so decoding is primarily a concern in server-side or pre-processing code.

A common pitfall is single-pass decoding. Some inputs contain double-encoded entities (an entity within an entity, like `&amp;lt;`), which require multiple decode passes to fully resolve. Naive decoders that perform only one pass leave partially-decoded output. A robust decoder either loops until no more entities remain or uses a parser that handles the full HTML specification.

Another consideration is which entities to decode. Decoding the five core entities is always safe, but decoding all named entities requires a complete entity table (the HTML5 specification defines over 2,000 named entities). For most use cases, decoding numeric entities and the core named entities is sufficient and avoids the complexity of maintaining a full entity table. When in doubt, use a well-tested library rather than a regex-based decoder.

  • Decoding reverses encoding, converting entities back to characters
  • Watch for double-encoded entities that require multiple decode passes
  • HTML5 defines over 2,000 named entities — most uses need only the core set
  • Prefer well-tested libraries over regex-based decoders

XSS Prevention Beyond Encoding

HTML encoding is a critical defense against XSS, but it is not the only one. A comprehensive XSS prevention strategy combines encoding with several other layers, each addressing different attack vectors. Relying on encoding alone leaves gaps that attackers can exploit.

Content Security Policy (CSP) is a powerful complementary defense. A well-configured CSP restricts which scripts can execute, blocks inline scripts by default, and limits the domains from which resources can be loaded. Even if an attacker manages to inject markup, a strict CSP prevents the injected script from running. CSP does not replace encoding — both should be used together.

Input validation reduces the attack surface by rejecting inputs that clearly do not belong. A username field should not contain angle brackets; a phone number field should not contain script tags. While validation is not a complete defense (attackers can craft inputs that pass validation but still exploit encoding gaps), it eliminates many obvious attack vectors and makes the remaining defenses more effective. Sanitization, which actively removes dangerous elements from HTML input, is appropriate when you must accept rich HTML content from users — use a well-vetted library like DOMPurify rather than attempting to sanitize with regex.

  • Use Content Security Policy to restrict script execution
  • Validate input to reject obviously malicious content
  • Sanitize rich HTML input with a vetted library like DOMPurify
  • Layer defenses: encoding, CSP, validation, and sanitization together

Best Practices for HTML Encoding

Adopt a consistent, context-aware encoding strategy across your entire application. Use a templating engine or framework that handles encoding automatically by default — most modern frameworks (React, Vue, Angular, Twig, Jinja) auto-escape output in their default configuration. Override the auto-escaping only when you have a specific reason and have verified the safety of the input.

Never build HTML by string concatenation with untrusted data. Even experienced developers make mistakes with concatenation, missing a context or applying the wrong encoding. Use the templating engine's variables and let it handle the escaping, or use a dedicated library that knows the context. If you must concatenate, document the security review clearly and have a second developer verify the encoding.

Test your encoding with adversarial input. The OWASP XSS Filter Evasion Cheat Sheet is a comprehensive catalog of attack techniques that bypass naive encoding. Run these against your application to verify that your defenses hold. Automated security scanners (ZAP, Burp) can also help identify encoding gaps in your application. Encoding is a small detail with outsized security impact — get it right.

  • Use frameworks that auto-escape output by default
  • Never build HTML by concatenation with untrusted data
  • Test with adversarial input from the OWASP XSS cheat sheet
  • Have a second developer review any code that overrides auto-escaping