C

Web › Module 2 › Lesson 5

BeginnerModule 2Lesson 5/6

Lab — XSS Challenge

Trigger reflected and stored XSS in a local lab, then fix with encoding and CSP

25 min+47 XP2 quiz
Module progress5 of 6

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 externally

3. 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 content

4. 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

1

Ethical XSS testing requires:

Multiple choice

Knowledge Check

2

True or False: html.escape on output stops script tags from executing in HTML body context.

True or False

← Previous

Answer all 2 knowledge checks to continue. (0/2 answered)