What is Cross-Site Scripting?
Cross-Site Scripting (XSS) is one of the most common vulnerabilities in web applications and has been part of the OWASP Top 10 for years. At its core, XSS describes the injection of malicious code — usually JavaScript — into a trusted web page. The attack targets the application's users, not the application itself: when a victim visits the manipulated page, the malicious code executes in their browser.
XSS is a client-side injection attack. The attacker exploits weaknesses in how the web application processes input — such as search fields, comment sections, forums or URL parameters. Anywhere user input is embedded into page content without proper sanitization, XSS can occur.
From a high level, cross-site scripting can be described as the embedding of foreign code into a trusted context for execution. Technically speaking, XSS describes a client-side injection attack in which an attacker aims to execute malicious code in a web browser of the victim by including mostly malicious JavaScript in a legitimate web page or web application. The actual attack will occur when the victim visits the target web application that executes the malicious code. It is important to understand that the web application becomes merely a vehicle to deliver the malicious code for attacking the user – the targeted web application is not being attacked itself. Typically, an attacker would look for XSS vulnerabilities on web applications allowing comments, forums, message boards or any other component of a web application that allows user input to be embedded in the sites' contents.
Usually when verifying XSS vulnerabilities, attackers tend to trigger alert boxes to demonstrate code execution within the browser. Such an alert box after a successful XSS attack might look like this:
This alert box has been spawned on a demo web application by accessing the following link:
https://x.x.x.x/search.php?keyword=cats<script>alert('XSS demo by e2 Security!')</script>
If this was a real web application vulnerable to an XSS attack, an attacker might now send the link above to a victim of choice, hoping for him to access the link. As the web application seems to embed the user input into its own context without any sanitization or encoding, a malicious JavaScript is likely to be executed in the victims' browser.
Types: Reflected, Stored and DOM-based XSS
XSS vulnerabilities are categorized into three main types based on how the payload is delivered:
Reflected XSS
In Reflected XSS, the malicious code is sent to the web application via a crafted link and immediately reflected back in the server response — without being stored. The attacker must trick the victim into clicking the prepared link (e.g. via email or phishing).
Example: A search field outputs the search term unfiltered on the results page. The attacker replaces the search term with JavaScript code that executes in the victim's browser.
Stored XSS
Stored XSS (also Persistent XSS) is the most dangerous variant. The malicious code is permanently stored on the server — for example in a database field, forum post or user profile. Every user who visits the affected page automatically becomes a victim, without needing to click a special link.
DOM-based XSS
In DOM-based XSS, the vulnerability lies entirely in client-side JavaScript code. The server is not directly involved — the attack manipulates the Document Object Model (DOM) in the victim's browser. This variant is harder to detect since server-side scanners often miss it.
What is the Risk?
Once an XSS vulnerability has been identified, an attacker will most likely try to inject JavaScript. The possibilities are extensive:
- Session Hijacking: Stealing session cookies to take over the victim's session
- Cross-Site Request Forgery (CSRF): Triggering actions on behalf of the user — transfers, password changes, orders
- Data Exfiltration: Extracting personal data, keystrokes (keylogger) or form contents
- Malware Distribution: Redirecting to malicious websites or drive-by downloads
- Defacement: Manipulating visible page content to deceive users
The risk primarily lies with the users of the web application. For businesses, however, an XSS vulnerability means potential reputational damage, data protection violations (GDPR) and — if admin accounts are affected — the danger of complete system compromise.
How to Detect and Prevent XSS
The OWASP XSS Prevention Cheat Sheet defines the key rules for preventing XSS:
- Rule #0: Never insert untrusted data except in explicitly allowed locations
- Rule #1: HTML-encode before inserting into HTML element content
- Rule #2: Attribute-encode before inserting into HTML attributes
- Rule #6: Sanitize HTML markup with a purpose-built library (e.g. DOMPurify)
- HTTPOnly Flag: Make cookies inaccessible to JavaScript
- Content Security Policy (CSP): Restrict inline scripts and external script sources
These measures apply at the web server configuration and source code level. A Web Application Firewall (WAF) can serve as an additional layer of protection but does not replace proper input sanitization in code.
Regular penetration tests and automated security scanners (DAST/SAST) help identify XSS vulnerabilities proactively before they are exploited.
XSS in Practice
XSS is comparatively easy to identify — hundreds of new vulnerabilities are reported daily. Two examples demonstrate the severity and complexity:
- Chrome XSS Bug (2.5 years to fix): A CSP bypass in Google Chrome required a change to the HTML specification itself — PortSwigger report
- Pandora FMS RCE via XSS chain: Chaining multiple vulnerabilities (including XSS) to achieve critical remote code execution — PortSwigger report
- Weglot Reflected XSS (CVE-2023-33999): Our own team identified and responsibly disclosed a reflected XSS vulnerability in the Weglot WordPress plugin — read the case study