DEV Community

Abhinav Singwal
Abhinav Singwal

Posted on

Master XSS the Practical Way: Introducing xss-labs

I built xss-labs, a free, open-source collection of 39 interactive XSS challenges. It runs entirely in your browser with no server and no setup required. It is perfect for developers, penetration testers, and anyone preparing for PortSwigger, TryHackMe, or bug bounty programs. The live demo is available at yogsec.github.io/xss-labs and the GitHub repository is at github.com/yogsec/xss-labs.

cross site scripting labs

Why Another XSS Lab

Cross-Site Scripting (XSS) remains number seven on the OWASP Top 10, and it continues to be a widespread vulnerability. The main reason is that developers still trust user input without proper sanitization.

The problem with most XSS tutorials is that they focus only on theory. Many require setting up a vulnerable virtual machine or a backend environment. They also fail to show real injection points across different contexts.

I wanted something different. I wanted a resource where you could open a URL and start hacking immediately without any installation. I wanted every major XSS vector covered, including reflected, stored, DOM-based, and event handler injections. I also wanted solutions included so learners understand why a particular payload works.

That is why I built xss-labs.

What Is Inside the 39 Labs

The labs are organized into logical categories. Each category focuses on a specific injection context.

The reflected XSS section covers GET parameter reflection, POST parameters simulated with sessionStorage, URL hash injection, Referer header mock, and User-Agent reflection.

The stored XSS section using frontend storage includes cookie value reflection, document.title injection, window.name persistence, localStorage key reflection, sessionStorage value reflection, IndexedDB read and render, cookie injection, cross-page navigation with window.name, history.state with pushState, Base64 decode and inject, and multi-key local storage.

The DOM-based XSS section demonstrates document.write with location.search, innerHTML with unsanitized input, insertAdjacentHTML injection, outerHTML replacement, eval() of user-controlled strings, setTimeout with user strings, setInterval injection, the Function() constructor, the javascript: pseudo-protocol in location.href, and dynamic script src injection.

The event handler XSS section covers onclick injection, onmouseover XSS, img onerror triggers, body onload payloads, onfocus with autofocus, oninput injection, onchange select XSS, onkeyup injection, and onsubmit form hijacking.

Each lab is a single HTML file. You can read the vulnerable code, try your own payloads, and click the solution button when you need help understanding the fix.

How to Use xss-labs

Using the labs takes less than thirty seconds. First, visit yogsec.github.io/xss-labs. Second, browse the lab index page to see all available challenges. Third, click on any lab to open it. Each lab contains a description of the vulnerability, an interactive vulnerable component, a real-time output reflection area, a collapsible hints section, and a solution panel with explanation and fix.

You can experiment with different payloads to understand how each attack vector works. All labs run locally in your browser. No malicious code is transmitted externally.

For the best learning experience, open your browser's developer tools and watch the network tab and console as you inject payloads.

Who Should Use These Labs

Web developers will benefit by learning how to avoid writing vulnerable code. Penetration testers can practice bypass techniques in a safe environment. Bug bounty hunters will recognize XSS vectors more quickly during real engagements. Students preparing for PortSwigger labs, TryHackMe, or the CEH practical exam can drill the basics before moving to advanced challenges. Self-taught hackers will find hands-on practice more valuable than reading CVEs.

The Technology Behind the Labs

The labs are built with HTML5, CSS3, and vanilla JavaScript. No frameworks are used to obscure the vulnerable logic. Bootstrap 5 is included only for layout purposes and does not affect security. The entire project is hosted on GitHub Pages, which means it is completely client-side and requires no backend server.

Every lab is deliberately simple so you can focus on the injection technique rather than framework complexity.

A Real-World Learning Example

Lab number seven demonstrates eval injection. The vulnerable code looks like this:

let userInput = new URLSearchParams(location.search).get('code');
eval(userInput);

An attacker could supply a payload such as code=alert(document.cookie) to execute arbitrary JavaScript. What you learn from this lab is that you should never pass user input to eval, setTimeout with a string, the Function constructor, or similar dynamic code execution functions. The lab shows you both the exploit and the fix, such as using JSON.parse or a whitelist approach.

Top comments (0)