Most XSS tutorials start with a payload, <script>alert(1)</script>, and treat the popup as the finish line. It is not. Getting a popup to fire proves a sink exists. It does not prove you understand why the browser trusted your input enough to run it, or what a real attacker actually does once they have that trust. Here is the order that gets you from zero to actually understanding this vulnerability, not just triggering it.
Step 1: Understand why the browser executes your input at all
Before touching a payload, look at what a vulnerable page is actually doing. Submit ordinary text into a search box or comment field, then view the page source and find exactly where that text landed in the HTML. If it was inserted without being encoded, the browser cannot tell the difference between "text the page wants to display" and "code the page wants to run." That single fact, the browser's inability to distinguish trusted markup from untrusted input unless something explicitly encodes it, is the entire vulnerability. Everything that follows is just different ways of exploiting that one gap.
Step 2: Get a reflected XSS to fire, on purpose, and explain why it worked
Reflected XSS is the right starting point because the feedback loop is immediate: you send input, the server echoes it straight back unencoded, and your script runs in your own browser, in your own session. TryHackMe's Intro to Cross-site Scripting room is built around exactly this progression. Get a payload to fire in a URL parameter or search field, then, before moving on, be able to explain in one sentence which part of the server's response your input landed in and why that placement let it execute. If you cannot explain that sentence, you have copied a payload, not learned the vulnerability.
Step 3: Prove impact beyond a popup
An alert() box demonstrates a sink exists. It does not demonstrate why anyone should care. The actual step here is upgrading that same reflected vulnerability into something with real consequence: exfiltrating a session cookie to a server you control, or silently redirecting the victim. This is where XSS stops being a curiosity and starts being the credential-theft and account-takeover vector it actually is in real engagements, and it is the step most tutorials skip entirely because a working alert() looks like success even when it demonstrates almost nothing.
Step 4: Learn stored XSS, where the victim is never you
Stored XSS changes the mental model completely. Instead of exploiting your own request, you plant a payload somewhere persistent, a comment field, a profile bio, a product review, and it fires later, for someone else, in their session, possibly with higher privileges than yours. The technical payload can look identical to Step 2's. What is different is the delivery: you are not attacking your own browser any more, you are attacking whoever reads that comment next, which is exactly why stored XSS is treated as more severe than reflected in almost every real-world risk assessment.
Step 5: Learn DOM-based XSS, where the server is not even involved
This is the step that trips people up most, because everything you learned about server responses in Steps 2 through 4 stops applying. DOM-based XSS lives entirely in the browser: client-side JavaScript takes untrusted input, from the URL, from document.referrer, from anywhere, and hands it to a sink like innerHTML or eval without ever sending it to the server at all. First identified as its own distinct category by researcher Amit Klein in 2005, it means you have to stop reading server responses in a proxy and start reading the page's own JavaScript for the specific line where untrusted data meets a dangerous sink.
Step 6: Learn to break through filters, because production code is never this clean
Every deliberately vulnerable training target so far has had no defences. Real applications encode output, strip tags, or run a Content Security Policy, and your Step 2 through 5 payloads will simply stop working against them. TryHackMe's Advanced Cross Site Scripting room picks up exactly here: case variation, encoding tricks, and finding the specific gap in a filter's logic rather than its intent. OWASP's Types of Cross-Site Scripting reference and its DOM-based XSS Prevention Cheat Sheet are worth reading at this stage specifically, because understanding the defence properly is what tells you which part of it is actually enforced and which part just looks like it is.
The vulnerability never changes. Only the delivery does
Every step above is still exploiting the exact fact from Step 1: something rendered untrusted input without encoding it. Reflected, stored, and DOM-based XSS are not three unrelated vulnerabilities to memorise separately, they are the same trust failure showing up in three different places, immediate, persistent, and client-side, and filter evasion is just what happens when someone tries, imperfectly, to patch that failure after the fact. Learn Step 1 properly and the other five stop being new vulnerabilities each time and start being the same idea in a new location.
Start the Intro to Cross-site Scripting room on TryHackMe
Frequently asked questions
Is XSS still relevant with modern frameworks that auto-escape output? Yes. Auto-escaping reduces the obvious cases but does not eliminate DOM-based XSS, unsafe use of dangerouslySetInnerHTML-style escapes, or third-party script inclusion, all of which show up constantly in real applications built on modern frameworks.
Do I need to know JavaScript well before Step 5? You need enough to read it, not necessarily write complex applications. Being able to trace where a variable's value came from and where it gets used is the specific skill DOM-based XSS actually requires.
Why does stored XSS count as more severe than reflected XSS? Because it does not require tricking a specific victim into clicking a crafted link. It fires automatically for anyone who views the infected content, which usually means a larger, less predictable set of victims.
What is the difference between a filter and a Content Security Policy? A filter tries to strip or encode dangerous input before it is rendered. A CSP is a browser-enforced rule about what scripts are allowed to run at all, regardless of what made it into the page, which is why a strong CSP can stop an XSS payload even after a filter has already failed.
Is alert(1) ever an acceptable way to demonstrate XSS in a real report? For an initial proof of concept, yes, but a professional report should also state the realistic impact, session theft, account takeover, defacement, not stop at the popup, which is exactly the gap Step 3 is meant to close early.
How long does it typically take to get comfortable with all three XSS types? Reflected usually clicks within a session or two. Stored follows quickly once reflected is solid. DOM-based takes longest for most beginners, specifically because it requires comfort reading JavaScript rather than just reading HTTP responses.




Nick O'Grady