Cross-Site Scripting remains one of the most common web vulnerabilities decades after its discovery. Understanding its core mechanism and categories is the essential foundation for the defensive techniques covered throughout this module.
1How Data Becomes Executable Code
At its core, XSS exploits a single, specific failure: application code inserting untrusted data into a page in a way the browser interprets as markup or script, rather than as inert, literal text. If a comment system takes a user's raw comment text and inserts it directly into the page's HTML โ via innerHTML, or unsanitized server-side templating โ then a comment containing <script>...</script> stops being displayed text and becomes real, executing JavaScript.
This is fundamentally an application-level failure, not a browser flaw: browsers correctly execute whatever valid script tags appear in a page's HTML โ the vulnerability is the application allowing untrusted, attacker-controlled data to become part of that HTML in the first place.
2Stored XSS: The Most Dangerous Category
Stored (also called 'persistent') XSS occurs when the malicious payload gets saved by the application โ in a database, a file, anywhere the application persists user-submitted content โ a comment, a user profile bio, a forum post, a support ticket message.
Once stored, the payload executes automatically for every subsequent user who views that content, without the attacker needing to trick each individual victim into clicking a malicious link. This makes stored XSS particularly dangerous and high-impact: a single successful injection can compromise every visitor to a popular page until the malicious content is identified and removed.
3Reflected And DOM-Based XSS
Reflected XSS involves a malicious payload embedded in a single request โ typically a crafted URL with a script tag in a query parameter โ that the server echoes back into the response without escaping it. This requires tricking a specific victim into clicking a malicious link (via phishing, a malicious ad, or similar), since the payload isn't persisted anywhere.
DOM-based XSS is distinct from both: the entire vulnerable data flow happens client-side, with no server involvement at all. Client-side JavaScript itself unsafely takes untrusted data โ commonly location.hash, location.search, or document.referrer โ and inserts it directly into the page via innerHTML or a similar unsafe sink, without any server-side processing ever seeing the malicious payload.
4Step-by-Step Breakdown
When User Input Becomes Executable Code. XSS happens when untrusted data โ text a user typed, a URL parameter, anything not fully controlled by the developer โ ends up rendered as actual executable HTML/JavaScript instead of inert text, letting an attacker run their own code in another user's browser session.
The Core Mechanism: Data Becomes Code. If a comment field's text is inserted directly into the page's HTML without any processing, and a user submits <script>steal(document.cookie)</script> as their 'comment', that string stops being displayed text and becomes real, executing JavaScript for every visitor who views it.
The Core XSS Mechanism. What fundamentally allows a piece of user-submitted text to become executing JavaScript on someone else's browser?
- โA fundamental flaw in how all browsers work, unrelated to app code
- โUntrusted input being inserted into the page's HTML without being treated as inert text
- โIt's always caused by the user's own device being compromised
Stored XSS: The Payload Persists. Stored (or 'persistent') XSS happens when the malicious script gets saved server-side โ in a comment, a profile field, a forum post โ and then executes for every single user who later views that stored content, making it the most dangerous category.
Stored XSS Characteristics. Why is stored XSS generally considered the most dangerous category of the three?
- โIt's technically harder for an attacker to write
- โThe malicious payload persists server-side and executes for every user who later views the affected content
- โIt only affects the attacker's own account
Reflected And DOM-Based: The Other Two Categories. Reflected XSS bounces the payload off the server in a single request/response, typically via a malicious URL a victim is tricked into clicking. DOM-based XSS never touches the server at all โ client-side JavaScript itself unsafely inserts untrusted data (like a URL fragment) directly into the page.
The Three XSS Categories. What distinguishes DOM-based XSS from both stored and reflected XSS?
- โIt always requires a database to store the payload
- โThe malicious data flow happens entirely client-side, never touching the server at all
- โIt only affects mobile browsers specifically
XSS Fundamentals Understood. You now understand the core mechanism behind XSS โ untrusted data becoming executable code โ and can distinguish stored, reflected, and DOM-based XSS, the foundation for the escaping and prevention techniques covered in the rest of this module.
Neutralize A Raw Script Injection. Render a user comment as literal text inside <code>, instead of raw, executable markup.
Level Up ๐
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1XSS Vulnerabilities Have No Direct Accessibility-Specific Dimension But Undermine Trust In The Entire Page
A compromised page can inject content that actively interferes with assistive technology (fake dialogs, hijacked focus), making baseline security a prerequisite for genuinely trustworthy accessible experiences.
SEO Implications
- 1
A Site Compromised By Stored XSS Can Suffer Severe, Direct SEO And Reputational Damage
Search engines actively flag and can deindex or warn users about compromised sites hosting malicious injected content, making XSS prevention a direct SEO risk-mitigation concern, not purely a security one.
Best Practices
Treat All User-Controllable Data As Untrusted By Default, Regardless Of Source
This includes not just form inputs, but URL parameters, HTTP headers, and even data from your own database if it originated from user input at any point โ trust boundaries matter more than data source labels.
Understand Which XSS Category Applies Before Designing A Fix
Stored XSS requires fixing the storage/rendering pipeline; DOM-based XSS requires auditing client-side JavaScript sinks โ misdiagnosing the category can lead to an incomplete fix.
Frequent Bugs
A comment section allows a submitted comment to execute JavaScript for every subsequent visitor.
This is stored XSS โ audit and fix the rendering pipeline to properly escape user content, covered in depth in the next lesson.
Client-side JavaScript reads a URL fragment and inserts it into the page, allowing a crafted link to execute arbitrary script.
This is DOM-based XSS โ audit all client-side code reading from location, document.referrer, or similar sources and inserting that data unsafely into the DOM.
Real-World Examples
Identifying A Stored XSS Vulnerability
A vulnerable comment feature where user input is inserted directly as HTML, allowing persistent script execution.
// VULNERABLE โ do not do this:
commentElement.innerHTML = userSubmittedComment;
// A comment like <img src=x onerror="steal()"> would execute for every viewer