🧭 Introduction
In this demonstration, we explore one of the most dangerous yet commonly found web vulnerabilities—Stored Cross-Site Scripting (XSS). Unlike its reflected counterpart, stored XSS involves injecting malicious scripts that are permanently stored on the target server, often within databases or files. When other users view the affected page, the malicious script is executed in their browser without their consent.
To illustrate how this vulnerability works in a controlled environment, we use DVWA (Damn Vulnerable Web Application) as our testbed and OWASP ZAP as our security testing tool. This setup allows us to safely simulate a stored XSS attack, observe the behavior of injected scripts, and understand how a poorly validated input field can open the door to serious client-side attacks.
✅ Manual XSS Testing
Step 1. Login to DVWA using default credentials as admin:password
Step 2: Go to DVWA Security (Left Side Bar Menu) set to Low settings
Step 3. Go to http://[localhost or 127.0.0.1]/dvwa/vulnerabilities/xss_s/

Step 4: Inject a simple payload like:
– Name: testuser
– Message: <script>alert('XSS')</script>
– Click ‘Sign Guestbook’ and see if an alert pops up.

The code appears in the response unsanitized.
“XSS Stored creates permanent, persistent attacks. To reset your test data: go to Setup (left sidebar) → click Create / Reset Database → test again.”

Troubleshooting (If not working)
“Troubleshooting DVWA security settings: If your DVWA is set to Low but not functioning correctly:
- Open More Tools → Web Developer Tools → Storage → Cookies
- Find the security value and change it from High to Low
- Remove any duplicate entries, keeping only one set to Low”

Reload the page. If the alert appears, the input was stored and executed = Stored XSS confirmed.
🧰 Testing with OWASP ZAP
ZAP is an excellent tool to automate XSS detection.
Active Scanning (Learn and develop this methodology)
Step 1: Launch your OWASP ZAP tool and set to Standard Mode by default.
Step 2: Go to Quick Start -> Select ‘Manual Explore’
– Enter your DVWA URL (mine might be different from yours in this demo)
– Click Launch Browser

Step 3: Browse the site (Using Builtin ZAP Browser)
– Login to DVWA using default credentials as admin:password
– Go to DVWA Security (Left Sidebar Menu) set to Low settings
– Go to XSS Store (Left Sidebar Menu) as identified test page for this demo.
Step 4. Spider the site (Specific to our target site)
– Look for /dvwa/vulnerabilities/xss_s/
that you’ve visited
– Right-click the target site in ZAP’s Sites tab.
– Select Attack → Spider.

A Spider window will pop up on your screen leave it as default and click Start Scan
– This spider or crawling is fast enough for testing but in real-world you need to wait a couple of minutes before running Active Scan. For additional details on OWASP ZAP spidering, check out my previous blog post.
Step 5: Run Active Scan:
– Right-click the site or specific page → Attack → Active Scan.
– An Active Scan window will pop up on your screen leave it as default then click Start Scan
– In real-world feel free to adjust the Policy in Active Scan window and see the results in different settings.
– ZAP will inject XSS payloads like:
<script>alert(1)</script> <img src=x onerror=alert(1)>

Step 6: View results
a. Go to the Alerts tab.
– Look for entries like: Cross Site Scripting (Reflected) and Cross Site Scripting (Stored)
b. Click on each alert to see:
– Vulnerable parameter
– Request/response with injected payload
– Proof of concept

Step 7: (Optional) Validate the result
– Go to Manual XSS Testing first section above and learn from it.
🧠 Pro Tip for XSS Researchers
If you’re testing stored XSS and want to see the malicious code without triggering it, try:
- Disabling JavaScript.
- Loading the vulnerable page.
- Viewing the page source (Ctrl+U) to see the stored payload.
- Re-enabling JavaScript once ready.
Option: Use a Browser Extension
Use NoScript (Firefox) or ScriptSafe/uBlock Origin (Chrome) to:
– Block/allow JavaScript per domain
– See what scripts are running
– Temporarily enable JS for specific pages
⚠️ Important Note:
XSS cannot directly spawn a reverse shell like server-side RCE or LFI can. However, XSS can be used as a pivot to achieve code execution indirectly by:
– Exploiting admin panels (e.g., injecting malicious JS in a place that an admin will later view),
– Sending payloads to interact with the internal network from the victim’s browser (e.g., using JavaScript to perform SSRF or port scanning),
– Or triggering browser-based exploits (e.g., via beef-xss
).
🧩 Final Thoughts
Stored XSS vulnerabilities can have severe consequences—ranging from session hijacking and credential theft to full account takeover—especially when administrators or privileged users view the injected content. This demo highlights the importance of input sanitization, output encoding, and the need for a robust Content Security Policy (CSP).
Using tools like OWASP ZAP makes it easier for security professionals and developers to identify XSS risks early in the development lifecycle. By understanding how stored XSS works in practice, we can better defend against it in real-world web applications and prevent malicious actors from turning seemingly harmless input fields into attack vectors.