Web › Module 2 › Lesson 5
Lab — XSS Challenge
Trigger reflected and stored XSS in a local lab, then fix with encoding and CSP
Opening
Pop an alert locally—then kill the bug
Use DVWA XSS (Reflected) and XSS (Stored) modules, or WebGoat XSS lessons on localhost. Your goal: prove execution in the browser, document the sink, then patch with proper encoding. Never paste XSS payloads into production sites, comment boxes, or support tickets you do not own.
1. Step 1 — Reflected XSS on DVWA
Start DVWA (if not already running)docker run --rm -it -p 8080:80 vulnerables/web-dvwa # Security → Low → XSS (Reflected)
docker run --rm -it -p 8080:80 vulnerables/web-dvwa # Security → Low → XSS (Reflected)
Enter a basic payload in the name field and observe script execution. Escalate to document.domain or a harmless alert to confirm context.
Sample reflected payloads (lab only)<script>alert(document.domain)</script> <img src=x onerror=alert(1)> "><svg onload=alert(1)>
<script>alert(document.domain)</script> <img src=x onerror=alert(1)> "><svg onload=alert(1)>
2. Step 2 — Stored XSS on DVWA
Open XSS (Stored). Submit a payload in the message board, then load the page in a fresh browser profile. Notice the payload fires for every visitor— that is why stored XSS is scarier.
Stored demo (no exfiltration to real servers)<script>console.log("stored-xss-lab", document.cookie)</script> # Check DevTools console only—do not send cookies externally
<script>console.log("stored-xss-lab", document.cookie)</script>
# Check DevTools console only—do not send cookies externally3. Step 3 — Fix with encoding
safe_render.py — escape on outputimport html def render_comment_unsafe(text: str) -> str: return f"<p>{text}</p>" # VULNERABLE def render_comment_safe(text: str) -> str: return f"<p>{html.escape(text)}</p>" # Safe in HTML body # In templates: use autoescape, not |safe on user content
import html
def render_comment_unsafe(text: str) -> str:
return f"<p>{text}</p>" # VULNERABLE
def render_comment_safe(text: str) -> str:
return f"<p>{html.escape(text)}</p>" # Safe in HTML body
# In templates: use autoescape, not |safe on user content4. Step 4 — Optional CSP header
Add CSP on your lab reverse proxyselfselfnone
selfselfnone
Complete XSS challenge lab
On local DVWA or WebGoat, successfully trigger one reflected and one stored XSS, identify the exact HTML sink, then apply html.escape or template autoescape so the same payload renders as harmless text.
Knowledge Check
Ethical XSS testing requires:
Multiple choice
Knowledge Check
True or False: html.escape on output stops script tags from executing in HTML body context.
True or False