Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 6

Understanding Cross-Site Scripting (XSS)

Recommended resources

Hello! In our previous lesson, we dove into SQL Injection, a vulnerability that targets an application's backend database. We saw how an attacker can manipulate server-side logic to bypass authentication and exfiltrate sensitive data. Today, we pivot from the server to the client.

This lesson explores the fundamental mechanics of Cross-Site Scripting (XSS), one of the most prevalent vulnerabilities on the web. Instead of attacking the server's data store, XSS targets the application's users. Your goal is to understand how an attacker can inject malicious scripts into a website, which are then executed by a victim's browser. Mastering these concepts is essential for any ethical hacker, as XSS flaws are a common finding in bug bounties and penetration tests.

What is Cross-Site Scripting?

At its core, Cross-Site Scripting is a client-side code injection attack. It occurs when an application includes untrusted data in its response without proper validation or encoding, allowing malicious scripts to be sent to a user's browser. The browser, trusting the server, executes the script.

This fundamentally breaks a core web security model: the Same Origin Policy (SOP). The SOP is designed to prevent a script from evil.com from accessing data (like cookies or page content) on your-bank.com. With XSS, an attacker injects their script into your-bank.com itself, so the script executes with the bank's origin. This gives it access to everything your browser can access on that site.

The following video from PwnFunction provides an excellent animated explanation of the Same Origin Policy and how XSS bypasses it.

Cross-Site Scripting (XSS) Explained

This video explains the security principle that XSS violates and the basic mechanism of injection.

First, watch the explanation of the Same Origin Policy. Then, continue with the segment that demonstrates a basic JavaScript injection to see how user input can become executable code.

As you saw, the vulnerability arises because the server reflects user input directly into the page source. The browser has no way to distinguish the attacker's injected script from the legitimate HTML and JavaScript of the page, so it executes it.

For a formal definition and overview, the PortSwigger Web Security Academy is an indispensable resource.

What is cross-site scripting (XSS) and how to prevent it?

This article from PortSwigger offers a clear definition of XSS and its core mechanism.

Please read the first two sections, What is cross-site scripting? and How does XSS work?. This will solidify your understanding of the vulnerability's definition and impact.


The Three Main Categories of XSS

XSS vulnerabilities are generally categorized based on how the malicious payload is delivered and stored. The three main types are Reflected, Stored, and DOM-based.

This matrix from OWASP provides a useful way to classify them based on two factors: where the untrusted data is used (Server vs. Client) and data persistence (Stored vs. Reflected).

This chart categorizes XSS attacks. Reflected and Stored XSS are typically server-side issues where the server includes malicious data in the page. DOM-based XSS is a client-side issue where JavaScript in the browser mishandles data.

Let's break down each of these types.

1. Stored XSS (Persistent or Second-Order)

Stored XSS is often considered the most dangerous type. The attack proceeds as follows:

  1. An attacker injects a malicious script into a web application where it gets stored permanently on the server, for instance, in a database. Common injection points include comment sections, user profiles, or forum posts.
  2. The application saves this malicious input.
  3. When any user (the victim) browses to the page containing the stored script, the server retrieves the script from the database and includes it in the HTML sent to the victim's browser.
  4. The victim's browser executes the script because it came from a trusted server.

The payload is persistent and can infect every user who visits the vulnerable page, including administrators with high-level privileges.

The video below from Cyber Ryan gives a fantastic practical demonstration of a Stored XSS attack against the Damn Vulnerable Web Application (DVWA).

Cross Site Scripting Explained with Real Examples (Stored, Reflected, DOM XSS)

This segment demonstrates how to find and exploit a Stored XSS vulnerability.

Watch the section on Stored XSS. Pay attention to how a simple <script>alert('XSS')</script> payload is first used as a proof of concept. Then, observe how more advanced payloads are used to steal cookies and deface the webpage, showcasing the real-world impact.

2. Reflected XSS (Non-Persistent)

In a Reflected XSS attack, the malicious script is part of the request sent to the web server and is "reflected" back in the HTTP response. It is not stored permanently.

  1. The attacker crafts a malicious URL containing a JavaScript payload (e.g., in a query parameter).
  2. The attacker tricks a victim into clicking this link through social engineering (e.g., a phishing email or a deceptive post).
  3. The victim's browser sends the malicious URL to the trusted website.
  4. The server takes the payload from the URL parameter and embeds it in the HTML response sent back to the victim.
  5. The victim's browser executes the script.

This attack flow is illustrated perfectly in the diagram below.

This diagram illustrates the five steps of a Reflected XSS attack, from the attacker crafting a malicious link to the victim's browser executing the script and compromising their session.

While it requires user interaction for each victim, Reflected XSS is still very dangerous, especially since the malicious link points to a legitimate, trusted domain.

Let's return to the Cyber Ryan video to see a demonstration of Reflected XSS.

Cross Site Scripting Explained with Real Examples (Stored, Reflected, DOM XSS)

This part of the video explains and demonstrates a Reflected XSS attack.

Watch the segment covering Reflected XSS. Note how the payload is contained within the URL and how this type of attack is often used in phishing campaigns.

3. DOM-based XSS

DOM-based XSS is a more subtle variant where the vulnerability lies entirely within the client-side code (i.e., the JavaScript running on the page).

  1. The application's client-side scripts take data from a user-controllable source, such as the URL fragment (#), and process it.
  2. This data is then written back into the Document Object Model (DOM) of the page in an unsafe way. A "sink" like innerHTML is often the culprit.
  3. An attacker crafts a URL that places a malicious payload in the source (e.g., http://vulnerable.site/page#<img src=x onerror=alert(1)>).
  4. When a victim visits this URL, the legitimate, but vulnerable, client-side script reads the payload from the URL and writes it to the DOM, causing it to execute.

The key difference is that the payload may never even be sent to the server. The entire attack flow happens within the victim's browser.

What is cross-site scripting (XSS) and how to prevent it?

This section of the PortSwigger article provides a concise explanation of DOM-based XSS with a clear code example.

Please read the section titled DOM-based cross-site scripting. Focus on understanding the concept of a "source" (like an input field or URL parameter) and a "sink" (like innerHTML).


Impact and Proof of Concept

As you've seen in the demonstrations, the impact of a successful XSS attack can be severe. An attacker can:

  • Hijack user sessions: By stealing session cookies, an attacker can impersonate a victim and gain full access to their account.
  • Perform unauthorized actions: The script can make requests on behalf of the user, such as changing their password, transferring funds, or deleting data.
  • Capture credentials: The attacker can inject a fake login form to phish for the user's username and password.
  • Deface the website: The script can modify the page content, causing reputational damage.
  • Deliver malware: The script can redirect the user to a malicious site or trigger a drive-by download.

For testing, ethical hackers often start with a simple, non-malicious payload to confirm the vulnerability. The most common proof-of-concept (PoC) is <script>alert(1)</script>. If a pop-up box with "1" appears, the page is vulnerable.


Conclusion

In this lesson, we have shifted our focus from server-side to client-side vulnerabilities by examining the mechanics of Cross-Site Scripting. You now have a foundational understanding of how untrusted user input can be weaponized to execute scripts in other users' browsers.

Here are the key takeaways:

  • XSS is a Client-Side Injection: The ultimate target is another user's browser, not the server's database.
  • It Bypasses the Same Origin Policy: By injecting script into a trusted origin, an attacker gains access to the user's data and session for that origin.
  • Three Core Types:
    • Stored XSS: The payload is saved on the server and affects all users who view it (high impact).
    • Reflected XSS: The payload is in the request and reflected back in the response, requiring social engineering for each victim.
    • DOM-based XSS: The vulnerability is in the client-side JavaScript that unsafely handles data from sources like the URL.
  • The Impact is Significant: Successful exploitation can lead to complete account takeover, data theft, and other malicious actions.

We've now explored two of the most critical web vulnerabilities. In the next lesson, we will look at Cross-Site Request Forgery (CSRF). While it also targets the client, CSRF works differently: instead of injecting code, it tricks a logged-in user's browser into sending an unintended, malicious request to a web application.