Skip to main content

Reflected XSS

Lab: DVWA
Scenario: Reflected Cross-Site Scripting
Difficulty: Beginner
Estimated Time: 25 minutes

Learning Objectives

By the end of this scenario, you will be able to:

  • Explain how reflected XSS differs from stored XSS (payload lives only in the immediate response).
  • Prove execution by showing a controlled script (e.g. alert) in the victim browser context.
  • Name context (HTML body vs attribute vs JavaScript) as the driver for encoding and bypass.
  • List detection and prevention controls relevant to reflected output.

Setup

Prerequisites

  • DVWA lab running at CSN Labs
  • Web browser (Chrome/Firefox recommended) with Developer Tools (F12)
  • Security level Low (DVWA → DVWA Security → set to Low → Submit)

Initial configuration

  1. Log into DVWA with your lab credentials.
  2. Confirm security is Low.
  3. Open Vulnerabilities → XSS (Reflected).

Scenario story

You are reviewing a page that greets the user by name. The value you submit is echoed back in the HTML response. If the app does not encode output for the HTML context, an attacker can inject a script that runs in your browser session—stealing cookies, keylogging, or performing actions as you.

Step-by-step walkthrough

Step 1: Baseline behavior

On XSS (Reflected), enter a harmless string, e.g. Alice, and submit.

Expected: The page shows something like Hello Alice (exact wording depends on DVWA version).

Observe: Open DevTools → Elements (or View Source) and find where your input appears in the HTML. Note whether it sits in plain text between tags, inside an attribute, or elsewhere—that is your sink context.

Step 2: Break out with a script

Try:

<script>alert('XSS')</script>

Submit the form.

Expected (Low security): A browser dialog appears (alert). That proves JavaScript execution in the page origin.

What happened: The server placed your string into the HTML without encoding < and >, so the browser parsed <script> as live markup.

Step 3: Tie to impact

Reflected XSS is often delivered via a link (?name=...) or form. The victim must visit the attacker-controlled URL while authenticated to a sensitive app—then the script runs as that user.

Check your understanding: Why is this “reflected”? Because the payload is not stored in a database for others; it is reflected once in the response to that request (contrast Stored XSS).

Step 4: Try context-aware payloads (optional)

If a basic script tag fails at higher security levels, testers try:

  • Event handlers: "><img src=x onerror=alert(1)>
  • Different encodings (URL-encoded) depending on filters.

Document what changed in the HTML when a payload fails—filters often strip or encode specific patterns.

Why this works

Reflected XSS occurs when untrusted input is copied into an HTTP response without context-appropriate encoding. The browser interprets the result as HTML or script. The root cause is missing or wrong output encoding, not “JavaScript in the database.”

Defender notes

How to detect

  • Code review: Find every place user input is concatenated into HTML, JSON rendered into pages, or SSR HTML.
  • Dynamic testing: Payload lists with benign callbacks (e.g. alert in lab, collaborator or logging in pro tests).
  • HTTP logs: Look for %3Cscript and other encoded XSS probes.

How to prevent

  1. Default escape for the correct context (HTML, attribute, JS, CSS, URL)—frameworks often provide helpers; use them at the last mile before output.
  2. Content-Security Policy (CSP) as defense in depth (not a substitute for encoding).
  3. Input validation only where it matches business rules; do not rely on blacklists alone for XSS.

Try these variations

Easy

  • Change the alert string; try String.fromCharCode style payloads if filters block quotes.

Medium

  • Identify the exact HTML snippet surrounding your input using Elements inspector.
  • Try a payload that fits attribute context if the app echoes inside a quoted attribute.

Hard

  • Compare Low vs Medium security in DVWA: note which characters are filtered and hypothesize the sanitizer logic.

Evidence checklist

Capture screenshots or notes showing:

  • Clean baseline submission.
  • Successful alert (or equivalent proof of execution).
  • HTML source or Elements view showing unencoded payload in the response.

Next steps