Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Academy Cross-Site Scripting (XSS)
Beginner · 20 min

Cross-Site Scripting (XSS)

Understand how attackers inject scripts into web pages and master the output encoding that stops them.

1 How XSS Works

Cross-Site Scripting (XSS) allows attackers to inject malicious JavaScript into pages viewed by other users. The browser executes this script in the context of the victim's session — enabling cookie theft, keylogging, or redirects.

Reflected XSS — the payload is in the URL/request and reflected back immediately:

<!-- URL: /search?q=<script>alert(document.cookie)</script> -->
<p>Results for: <?= $_GET['q'] ?></p>

Stored XSS — the payload is saved to the database and rendered for every visitor. More dangerous because it's persistent and affects all users who view that content.

2 Output Encoding — The Fix

The fundamental defense is to HTML-encode output so that special characters are rendered as text rather than executed as markup:

  • &&amp;
  • <&lt;
  • >&gt;
  • "&quot;
  • '&#x27;

Most templating engines escape by default — React's JSX, Django templates, Jinja2, Blade, Twig. The risk is when you bypass escaping intentionally:

// UNSAFE — renders raw HTML
<div dangerouslySetInnerHTML={{ __html: userContent }} />

// SAFE — React escapes automatically
<div>{userContent}</div>

3 Content Security Policy & DOM XSS

DOM-based XSS occurs entirely in the browser. Scripts read attacker-controlled data (e.g., location.hash) and write it to the DOM via innerHTML, document.write, or eval.

// UNSAFE — DOM XSS
document.getElementById('msg').innerHTML = location.hash.slice(1);

// SAFE — use textContent instead
document.getElementById('msg').textContent = location.hash.slice(1);

Content Security Policy (CSP) is a defense-in-depth header that restricts what scripts can execute: Content-Security-Policy: default-src 'self'; script-src 'self'. It won't replace output encoding but limits the blast radius of any bypasses.

Knowledge Check

0/4 correct
Q1

What distinguishes stored XSS from reflected XSS?

Q2

Which JavaScript property should you use instead of innerHTML to safely display user text?

Q3

React automatically escapes JSX expressions. When does this protection NOT apply?

Q4

What does a Content Security Policy (CSP) do?

Code Exercise

Escape User Output

The function below writes user-controlled text directly into the DOM using innerHTML, creating a XSS vulnerability. Fix it by using textContent instead.

javascript