The Gift That Keeps on Giving
If reflected XSS is throwing a punch, stored XSS is planting a landmine. You set it once, and it detonates every time someone walks by. No social engineering needed after the initial setup - every visitor becomes a victim automatically.
Stored XSS (also called Persistent XSS) occurs when your malicious payload is saved by the application - in a database, file system, or anywhere persistent - and later displayed to other users. It's the most dangerous form of XSS because it scales: one injection, thousands of victims.
Reflected XSS
The Attack Flow
Unlike reflected XSS where the payload round-trips with each request, stored XSS separates the injection from the execution:
Where to Find Stored XSS
Any feature that saves user content and displays it to others is a potential stored XSS vector:
Classic Targets
Real-World Examples
Second-Order (Blind) Stored XSS
Sometimes your payload is stored but you never see it execute. It triggers somewhere else - maybe in an admin panel, a different application, or a report you don't have access to. This is called second-order or blind stored XSS.
Advanced Exploitation
Because stored XSS runs automatically on every page load, you can do more sophisticated attacks:
XSS Worm (Self-Propagating)
Persistent Session Hijacking
Keylogger Injection
Admin Action Automation
Bypassing Stored XSS Defenses
Because stored content often goes through more processing, there are unique bypass opportunities:
Encoding Mutations
Rich Text Editor Bypass
Character Set Issues
Testing Methodology
Stored XSS Hunting
- List every feature that saves user input
- Note where stored content is displayed
- Consider admin/backend views too
- Use unique strings like xss-test-123-comment
- Track where each identifier appears
- Note any encoding changes
- Start with <script>alert(document.domain)</script>
- Try event handlers if scripts blocked
- Test in ALL places where content appears
- Same content may appear in different contexts
- Profile page vs comment section vs email notification
- Different contexts need different payloads
- Use callback payloads (XSSHunter, Burp Collaborator)
- Inject in less obvious places (User-Agent, Referrer)
- Wait - some XSS triggers days/weeks later
Blind XSS Payloads
Practice Challenges
Knowledge Check
Key Takeaways
- Stored XSS persists - inject once, compromise every future visitor to that page
- Target high-traffic features: comments, profiles, chat messages, forum posts
- Don't forget admin panels - XSS in logs, support tickets, or user management is extremely high impact
- Blind XSS requires callbacks - use tools like XSSHunter or your own server to detect execution
- XSS worms can go viral - self-propagating XSS spreads exponentially (and is very illegal on production systems)