Lab 9: DVWA XSS Stored Lab 2026 — One Payload Hacks Every User (Persistent XSS Exploit Guide)
Mr Elite ··
14 min read ·
Hacking Labs -- Day 9
🧪 DVWA Lab Series — #9 of 30 Topic: XSS Stored — Persistent Injection Affecting All Users Next: Weak Session IDs →
⚠️ Lab Environment Only: Stored XSS techniques demonstrated here must only be practised against your own DVWA installation or authorised targets within a bug bounty programme scope. Injecting persistent JavaScript into real applications without authorisation is illegal under computer fraud laws worldwide.
DVWA XSS stored lab 2026 is where cross-site scripting stops being a single-victim attack and becomes something far more dangerous — a persistent payload that executes for every user who visits a page, indefinitely, without requiring any crafted URL or social engineering. Inject it once and it runs in every authenticated session that loads the guestbook. You are going to inject it, escalate it to cookie theft, bypass two different filter implementations, and understand precisely why stored XSS is rated a severity level higher than reflected everywhere it appears.
🎯 What You’ll Master in Lab 9
Understand why stored XSS affects all users — not just the injecting attacker
Inject a persistent alert payload into the DVWA guestbook at Low security
Escalate to a multi-user cookie theft payload with a netcat listener
Bypass the client-side length limit using Burp Repeater at Medium security
Bypass the script tag filter using event handlers at Medium and High security
⏱️ 55 min read · 3 hands-on exercises
📊 Have you completed the XSS Reflected lab (Lab 8)?
✅ This lab builds on the reflected XSS concepts from Lab 8. If you have not done Lab 8, start there first — the filter bypass techniques transfer directly. If you are comfortable with reflected XSS, the stored lab adds the persistence dimension and multi-user impact that changes everything about the risk assessment.
In Lab 8 you exploited reflected XSS — a payload delivered through a crafted URL that executes once, in one victim’s session. Stored XSS removes both of those limitations. No crafted URL needed. Executes in every session. The DVWA lab series sequences these two labs deliberately — you need to understand reflected XSS mechanics before stored XSS impact fully registers.
Stored vs Reflected XSS — Why Persistence Changes Everything
Reflected XSS requires three things to work: a vulnerable parameter, a crafted URL containing the payload, and a victim who clicks that URL. The attack is one-time and targeted — the attacker must actively deliver the payload to each victim. If nobody clicks the URL, nobody is affected.
Stored XSS requires only one thing: a vulnerable input field that saves user data to the database without encoding. Once the payload is injected, it is stored permanently. Every subsequent request to the affected page retrieves the payload from the database and includes it in the HTML response. Every visitor — authenticated or not, targeted or not — executes the payload. The attacker does nothing after the initial injection.
securityelites.com
Stored vs Reflected XSS — Attack Flow Comparison
REFLECTED XSS
1. Attacker crafts URL
2. Sends URL to victim
3. Victim clicks URL
4. Server reflects payload
5. One victim affected
STORED XSS
1. Attacker injects payload
2. Payload stored in DB
3. Any user visits page
4. DB returns payload
5. ALL users affected forever
📸 Stored vs reflected XSS comparison — reflected requires victim interaction with a crafted URL; stored requires zero victim interaction after initial injection and affects all subsequent visitors indefinitely.
Low Security — Persistent Alert to Multi-User Cookie Theft
⚡ EXERCISE 1 — KALI TERMINAL (20 MIN)
Inject a Stored XSS Payload and Confirm It Executes for Every Page Load
✅ What you just learned: The critical difference from Lab 8 is Step 4 — the payload fires for a completely different user who never submitted anything suspicious. This is the defining characteristic of stored XSS: it transforms a single injection event into a persistent, self-triggering attack against every subsequent visitor. The cookie theft payload you injected is now silently stealing session cookies from every DVWA user without any further action from you. This is exactly the impact model that justifies Higher severity ratings for stored vs reflected XSS in every bug bounty programme.
📸 Screenshot the netcat listener showing cookies received from two different user accounts and share in #dvwa-labs on Discord. Tag #storedxss2026
The Multi-User Impact — Why Stored XSS Gets Higher Severity
The severity difference between stored and reflected XSS comes down entirely to the user interaction requirement. Bug bounty severity frameworks — both HackerOne’s and CVSS — factor in whether an attack requires victim interaction. Reflected XSS requires a victim to click a link. Stored XSS requires nothing beyond the initial injection — every subsequent user is automatically affected.
In a real application, a stored XSS payload in a public comment section, product review, or forum post could silently steal session cookies from thousands of authenticated users per day without any suspicious links being sent to anyone. The application continues to look completely normal to users, administrators, and monitoring systems — there are no failed requests, no error logs, no anomalous traffic from the victims’ perspective. The payload executes as legitimate page content.
Medium Security — Burp Length Bypass and Event Handler Injection
⚡ EXERCISE 2 — KALI TERMINAL (20 MIN)
Bypass the Client-Side Length Limit and Script Tag Filter at Medium Security
⏱️ Time: 20 minutes · DVWA Medium security, Burp Suite running
MEDIUM SECURITY — LENGTH BYPASS + EVENT HANDLER
## MEDIUM SECURITY PROTECTION 1: maxlength=”50″ on message field
## Burp intercepts the POST before the browser limit applies
## Step 1: Enable Burp intercept, submit the guestbook form
## Step 2: In Burp Intercept — modify the mtxMessage parameter:
Alert fires with cookie value — stored XSS confirmed at Medium
## Alternative bypass: SVG onload
mtxMessage=<svg onload=alert(1)>
## Alternative: body onload (if full HTML injection possible)
mtxMessage=<body onload=alert(1)>
✅ What you just learned: Medium security’s two protections — client-side length limit and script tag stripping — are both trivially bypassed through different vectors. Burp Repeater bypasses client-side controls completely because it operates at the network layer, after the browser’s form validation. Script tag stripping fails because HTML has dozens of event-handler-capable tags that are not filtered. The lesson is identical to Lab 8’s Medium section: blacklists that block specific tags while ignoring event handlers provide no real security.
📸 Screenshot the stored onerror payload executing and share in #dvwa-labs on Discord.
High and Impossible Security — Filter Analysis and the Correct Fix
High security in DVWA’s stored XSS module applies a more aggressive regular expression that strips a wider range of HTML tags. The bypass technique is the same as reflected XSS High — use tags not included in the filter’s blacklist. The <img src=x onerror=alert(1)> payload continues to work at High because the filter targets script tags specifically without covering all event-handler-capable HTML elements.
The Impossible security level uses htmlspecialchars() with ENT_QUOTES on all input before storing it — the same correct fix used in the reflected XSS Impossible level. With this encoding, any injected HTML characters (< > " ' &) are converted to their HTML entity equivalents before database storage, meaning they are rendered as literal text characters rather than parsed as HTML by the browser. This approach cannot be bypassed through tag variation or encoding tricks because it encodes the structural characters HTML requires, not just specific tag names.
⚡ EXERCISE 3 — KALI TERMINAL (15 MIN)
Test the Stored XSS Payload Across All Four Security Levels Systematically
⏱️ Time: 15 minutes · DVWA all security levels
ALL SECURITY LEVELS — SYSTEMATIC STORED XSS TEST
## For each security level: inject, reload, test in second account
Payload (in Burp): <img src=x onerror=alert(document.cookie)>
Result: FIRES for all users ✓
## HIGH: Stronger regex → same onerror bypass still works
Payload (in Burp): <img src=x onerror=alert(document.cookie)>
Result: FIRES for all users ✓
## IMPOSSIBLE: htmlspecialchars() on storage → no bypass exists
Payload: <script>alert(1)</script>
Stored as: <script>alert(1)</script>
Rendered: <script>alert(1)</script> as literal text — no execution
## View source at Impossible level to see encoding in action:
Ctrl+U in Firefox → search for your injected payload text
Every < and > is encoded as < and > — cannot be parsed as HTML
✅ What you just learned: The systematic comparison across all four levels makes the security progression concrete — Low has no protection, Medium has bypassable blacklists, High has stronger but still bypassable blacklists, and Impossible uses the only approach that actually works: encoding. The view source at Impossible level is the most important step — seeing <script> in the HTML source, rendered as literal text in the browser, is the clearest possible illustration of why output encoding prevents XSS where every blacklist approach fails.
📸 Screenshot the view source at Impossible level showing encoded characters and share in #dvwa-labs on Discord.
XSS Worm Concept — How Stored XSS Self-Propagates
An XSS worm is the ultimate demonstration of stored XSS impact. The classic example is the Samy worm — written by Samy Kamkar in 2005, it spread to over one million MySpace profiles in under 24 hours by exploiting a stored XSS vulnerability in the profile page. The payload, when executed in a victim’s browser, automatically sent an HTTP request (using the victim’s authenticated session) to add Samy as a friend and copy the payload to the victim’s own profile — which then infected every visitor to that profile.
The mechanism in DVWA terms: a worm payload in the guestbook would use JavaScript’s fetch() or XMLHttpRequest to POST the same payload back to the guestbook submission endpoint, using the victim’s own CSRF token (readable from the page DOM). This is theoretical in DVWA’s lab context — implementing it requires CSRF token extraction — but the concept is what bug bounty hunters and security teams need to understand when assessing the risk of stored XSS in any user-generated content feature.
🧠 QUICK CHECK — Lab 9
You inject a cookie-theft payload into a website’s comment section. The comment is approved and published. The next day, you receive 847 session cookies from different users in your listener. Nobody clicked any link you sent. What type of XSS is this, and what does the 847 cookies tell you?
📋 Key Techniques — DVWA XSS Stored Reference Card
<script>alert(document.cookie)</script>Low security persistent payload — fires every page load for all users
<svg onload=alert(1)>Alternative event handler bypass — SVG onload not filtered at Medium
Burp Intercept → modify mtxMessageBypass client-side maxlength — server does not validate length
nc -lvnp 8888Start cookie theft listener before injecting exfiltration payload
Reset DVWA database after labRemove all stored payloads — click Setup/Reset DB in DVWA nav
🏆 Mark Lab 9 as Complete
You now understand stored XSS at the level needed to find, exploit, and report it in real applications. The multi-user impact you demonstrated in Exercise 1 is exactly what justifies Critical ratings in bug bounty programmes with large user bases.
Why is stored XSS more dangerous than reflected XSS?
Stored XSS is saved in the database and executes automatically for every subsequent visitor — no crafted URL needed. Reflected XSS requires tricking each victim into clicking a malicious link. Stored is self-propagating once injected, which is why it receives higher severity ratings.
What is the DVWA XSS Stored module testing?
It simulates a guestbook where user messages are stored and displayed to all visitors. The name and message fields store input without sanitisation at Low and Medium levels, demonstrating how user-generated content features — comments, reviews, profiles — become persistent XSS vectors.
How do you bypass the character limit on the DVWA stored XSS field?
The maxlength attribute is a client-side HTML control enforced only by the browser. Burp Suite bypasses it by intercepting the POST request after it leaves the browser but before reaching the server. Modify the message parameter in Burp Repeater to any length — the server accepts it regardless.
What is an XSS worm?
A self-replicating payload that, when executed in a victim’s browser, automatically posts the same payload to the application using the victim’s session — spreading to every new visitor. The Samy worm in 2005 infected one million MySpace profiles in under 24 hours using exactly this mechanism.
How do you clean up stored XSS payloads in DVWA?
Navigate to Setup/Reset DB in DVWA’s navigation and click Create/Reset Database. This drops and recreates all tables including the guestbook, removing all stored payloads. Always reset between testing sessions to start from a clean baseline.
What comes after XSS Stored in the DVWA lab series?
Lab 10 covers Weak Session IDs — testing predictable DVWA session token generation. After understanding how XSS steals session cookies, Weak Session IDs shows what makes those cookies guessable in the first place. Together Labs 8, 9, and 10 complete the session-based attack chain.
← Previous
Lab 8: DVWA XSS Reflected Lab 2026
Next →
Lab 10: DVWA Weak Session IDs Lab 2026
📚 Further Reading
DVWA XSS Reflected Lab 2026— Lab 8 covers reflected XSS — the prerequisite techniques for understanding stored XSS, including filter bypass methods and the cookie theft workflow.
XSS Cross-Site Scripting Tutorial— The complete XSS guide covering all three types — reflected, stored, and DOM-based — with real-world examples and the CSP defence mechanism.
DVWA Lab Series Hub— The complete 30-lab DVWA index covering every vulnerability class from brute force through advanced injection and cryptography.
PortSwigger Stored XSS Labs— Official PortSwigger stored XSS training with five progressive labs covering basic stored injection, DOM sink contexts, and stored XSS in attribute and JavaScript contexts.
OWASP XSS Attack Reference— Authoritative OWASP XSS documentation covering all three types, browser parsing behaviour, prevention techniques, and the Samy worm case study in detail.
ME
Mr Elite
Owner, SecurityElites.com
The stored XSS finding that changed how I think about impact happened on an e-commerce platform. The vulnerability was in a product review field — injected payload, straightforward img onerror technique. I set up a listener and walked away. I came back six hours later to find over 2,300 session cookies sitting in my log — customers browsing product reviews throughout the day, every one of them silently sending their session token to my server. No alert popups. No suspicious behaviour. Just a completely normal-looking review page, silently harvesting authenticated sessions from anyone who read it. I cleaned up, deleted the payload, and reported it as Critical. The company fixed it in two hours and sent me a very apologetic email alongside the bounty. The 2,300 cookies in the log still live in my notes as the most visceral illustration of why stored XSS severity ratings are what they are.