Introduction: The 1999 Bug That Won't Quit

Cross-Site Scripting (XSS) is often misunderstood as a "low-impact" vulnerability because it frequently pops up in demos with harmless alert() boxes. However, as evidenced by the IBM X-Force Cloud Security Landscape report and its perennial spot in the OWASP Top 10, XSS remains a critical gateway to account takeover and data theft.

Today's lab focuses on Reflected XSS into HTML context with nothing encoded — the most fundamental form of this vulnerability. Before diving into the solution, it's worth noting a critical shift in browser behavior: Chrome's recent restrictions on the alert() function (detailed by PortSwigger's James Kettle in "Alert() is Dead, Long Live Print()"). While alert() still works for demonstration purposes in isolated lab environments, the industry is moving toward print() for reliable testing.

With that context in mind, let's break down how a lack of sanitization allowed me to take control of the page.

Step 1: Understanding the Types of XSS

Before executing the attack, it's crucial to know what we're looking for. There are three primary flavors of XSS:

  • Reflected XSS: The malicious script comes from the current HTTP request (e.g., a URL parameter). This is what we're exploiting today.
  • Stored XSS: The script is saved on the server (e.g., a comment section) and served to every visitor.
  • DOM XSS: The vulnerability exists in client-side JavaScript rather than server-side code.

Step 2: The Reconnaissance Phase (Testing for Sanitization)

The lab provides a simple search bar. As an attacker or penetration tester, the first question is always: "Is the application validating my input, or is it echoing exactly what I type?"

To test this, I avoided using JavaScript immediately. Instead, I searched for a simple HTML header tag:

<h1>Your Lab is Hacked</h1>

Result: The text appeared on the page rendered as a large header, not as plain text. This confirms the application is not performing any HTML encoding or sanitization. The server is treating my input as part of the page structure.

None

(Note: I verified this by inspecting the page source using the browser's Developer Tools (F12). The <h1> tags were injected directly into the DOM.)

Step 3: Exploitation (The Payload)

Since the application allows arbitrary HTML tags, it almost certainly allows <script> tags. The classic payload for this scenario is:

<script>alert()</script>

I typed this into the search bar and hit enter. The browser interpreted the JavaScript and executed the alert function, successfully solving the lab.

Alternative Method: Direct URL Injection

In a real-world Reflected XSS scenario, the attacker wouldn't use the search bar themselves; they would trick a victim into clicking a link. The URL for this lab demonstrates that perfectly:

https://0a3500e204766e4581ee1b4000bd0001.web-security-academy.net/?search=<script>alert()</script>

By simply pasting that crafted URL, the payload executes instantly. This highlights why phishing campaigns and link shorteners are so dangerous when paired with unpatched XSS flaws.

None

Historical Context & Mitigation

It's fascinating (and concerning) that this vulnerability class has been around since roughly 1999. One of the most famous historical examples was the Samy Worm on MySpace, where Samy Kamkar used a Stored XSS payload to gain over one million followers in a single day.

How do we prevent this? As I learned from the fantastic walkthrough by Byte Monk and Pwn Function, relying on manual blacklists is futile. Proper defense involves:

  1. Contextual Output Encoding: Converting dangerous characters like < to < so the browser treats them as text, not code.
  2. Content Security Policy (CSP): Strict rules that tell the browser, "Only execute scripts from this specific domain."
  3. DOMPurify: A robust JavaScript library that sanitizes HTML on the client side, removing malicious code while keeping safe formatting.

Conclusion

Completing this lab from PortSwigger reinforces that the simplest bugs are often the most dangerous. While the payload was trivial, the lack of input validation observed here is a gateway to credential theft and session hijacking.

Resources Used for this Study:

Day 1 of Cybersecurity Learning Complete. On to the next lab.