British Airways Lost $230 Million Because of a Script
In 2018, British Airways disclosed a breach that exposed the payment card details of roughly 380,000 customers. The attack vector? A malicious script injected into the airline's payment page — a textbook cross-site scripting exploitation. The UK's Information Commissioner's Office initially proposed a fine of £183 million. That single vulnerability in a web application cost the company its reputation, customer trust, and a staggering amount of money.
If you've searched for cross-site scripting explained, you're looking for more than a dictionary definition. You want to understand how these attacks actually work, why they're so dangerous, and what you can do to protect your organization. That's exactly what I'm going to break down — with real incidents, specific attack mechanics, and defensive steps that go beyond the generic advice.
Cross-site scripting, universally known as XSS, has been a top web application vulnerability for over two decades. It consistently appears in the OWASP Top 10, and for good reason. It's easy to exploit, hard to detect, and devastatingly effective.
What Is Cross-Site Scripting, Really?
At its core, XSS is an injection attack. A threat actor inserts malicious code — almost always JavaScript — into a trusted website. When a victim visits that site, their browser executes the malicious script because it trusts the domain serving it. The browser has no way to know the script wasn't supposed to be there.
Think of it this way: your browser trusts the websites you visit. XSS exploits that trust by hiding attacker code inside legitimate pages. The victim's browser does exactly what it's designed to do — it runs the code. That code can steal session cookies, capture keystrokes, redirect users to phishing sites, or even rewrite the page content entirely.
I've seen XSS used to hijack admin sessions in corporate web applications, steal credentials from internal portals, and serve as the initial entry point for much larger data breach campaigns. It's rarely the flashiest attack, but it's one of the most reliable tools in a threat actor's arsenal.
The Three Types of XSS Attacks You Need to Know
Reflected XSS: The Drive-By Attack
Reflected XSS is the most common type. The malicious script is embedded in a URL or form input. When the victim clicks a crafted link — often delivered through a phishing email or social engineering message — the server reflects the script back in its response. The browser executes it immediately.
Here's a simplified example. Imagine a search page that displays your query: "You searched for: [your input]." If the application doesn't sanitize that input, an attacker can craft a URL where the search query is actually a script tag. The victim clicks the link, the page renders, and the malicious JavaScript fires.
Reflected XSS is the bread and butter of credential theft campaigns. Attackers pair it with convincing phishing emails to trick employees into clicking links that look like they lead to legitimate internal applications.
Stored XSS: The Silent Trap
Stored XSS is more dangerous because the malicious script is permanently saved on the target server — in a database, a forum post, a comment field, or a user profile. Every user who views that content gets hit. No special link required.
The British Airways breach I mentioned earlier involved a supply chain attack that injected a modified script into pages served to every customer. While the precise mechanics were more nuanced than a simple stored XSS, the principle is the same: malicious code persists on the server and executes for every visitor.
I've personally encountered stored XSS in customer support ticketing systems. An attacker submits a "support ticket" containing a script. When a support agent opens the ticket in their browser, the script executes in the agent's authenticated session — often with elevated privileges.
DOM-Based XSS: The Client-Side Ghost
DOM-based XSS never touches the server. The vulnerability exists entirely in the client-side JavaScript code. The page's own scripts read data from the URL or other user-controllable sources and write it into the page without proper sanitization.
This type is harder to detect with traditional server-side security tools because the malicious payload never appears in HTTP requests or responses on the server. It lives and dies in the browser. Modern single-page applications built with JavaScript frameworks are particularly susceptible if developers aren't careful about how they handle user input in the Document Object Model.
Why XSS Is More Dangerous Than Most People Think
Many organizations treat XSS as a low-severity finding. That's a mistake I see repeatedly. Here's what a successful XSS attack actually enables:
- Session hijacking: The attacker steals a user's session cookie and impersonates them — no password needed. If that user is an admin, the attacker now has admin access.
- Credential harvesting: The injected script can overlay a fake login form on the real page. The user enters their credentials, and they go straight to the attacker.
- Malware delivery: XSS can redirect users to pages hosting exploit kits or ransomware payloads.
- Keylogging: A script can capture every keystroke a user types on the compromised page.
- Defacement and disinformation: The attacker can rewrite page content, displaying false information under the authority of a trusted domain.
The 2022 Verizon Data Breach Investigations Report highlighted that web application attacks remain one of the top patterns in confirmed breaches. XSS is a primary enabler of those attacks. You can review the full findings in the Verizon DBIR.
How Do You Detect Cross-Site Scripting?
This is the question I get asked most often, so here's a direct answer. You detect XSS through a combination of automated scanning, manual code review, and penetration testing:
- Automated scanners like OWASP ZAP or Burp Suite can identify reflected and stored XSS in web applications by fuzzing inputs with common payloads.
- Manual code review is essential for DOM-based XSS. Look for any place where user-controllable data is written to the page —
innerHTML,document.write,eval(), and similar sinks. - Penetration testing by skilled professionals will find the edge cases that automated tools miss. Testers combine XSS with social engineering to demonstrate real-world impact.
- Bug bounty programs give external researchers an incentive to find and report XSS before threat actors exploit them.
If you're only relying on automated scanning, you're catching maybe 60-70% of XSS vulnerabilities. The rest require human analysis.
Defending Against XSS: What Actually Works
Input Validation and Output Encoding
This is the foundation. Every piece of user input must be validated against a strict allowlist — not a blocklist. You're defining what's allowed, not trying to catch everything that's malicious. Blocklists always have gaps.
Output encoding is equally critical. When you render user-supplied data on a page, encode it for the specific context — HTML body, HTML attributes, JavaScript, CSS, or URL parameters each require different encoding. The OWASP XSS Prevention Cheat Sheet is the definitive reference here.
Content Security Policy (CSP)
A properly configured Content Security Policy header tells the browser which scripts are allowed to execute on your pages. A strict CSP that blocks inline scripts and limits script sources to trusted domains can neutralize most XSS payloads, even if an attacker manages to inject code.
I've seen organizations deploy CSP in report-only mode first to identify what would break, then enforce it gradually. That's the right approach. A misconfigured CSP gives you a false sense of security and breaks legitimate functionality.
HTTPOnly and Secure Cookie Flags
Setting the HTTPOnly flag on session cookies prevents JavaScript from accessing them. This won't stop XSS itself, but it blocks the most common exploitation technique — session hijacking. Pair it with the Secure flag to ensure cookies are only transmitted over HTTPS.
Multi-Factor Authentication as a Safety Net
Even if an attacker steals a session cookie or captures credentials through XSS, multi-factor authentication adds a layer that makes exploitation significantly harder. It's not an XSS fix — it's a defense-in-depth measure that limits the blast radius of a successful attack.
Framework-Level Protections
Modern web frameworks like React, Angular, and Vue automatically escape output by default. If your development team is using these frameworks correctly, many XSS vectors are eliminated. The key word is "correctly." I've reviewed codebases where developers used React's dangerouslySetInnerHTML to bypass built-in protections because it was "easier." That's the equivalent of removing the safety from a loaded weapon.
The Human Element: Your Biggest XSS Risk Factor
Here's what most technical guides won't tell you: the majority of reflected XSS attacks succeed because someone clicks a malicious link. That link arrives via phishing email, a social media message, or a compromised website. The technical vulnerability matters, but the human decision to click is what triggers the exploit.
This is why security awareness training is non-negotiable. Your developers need to understand how to write secure code. Your employees need to recognize phishing attempts and suspicious links. Your security team needs to know how to test for and respond to XSS.
If you're building a security awareness program, our cybersecurity awareness training course covers XSS, social engineering, credential theft, and other threats your employees face daily. For organizations specifically focused on the phishing vector that delivers most reflected XSS payloads, our phishing awareness training for organizations provides targeted phishing simulation exercises and education.
Zero Trust and XSS: Why Perimeter Thinking Fails
Traditional perimeter security assumes everything inside your network is trusted. XSS attacks exploit that assumption perfectly — the malicious code executes inside the user's browser, within a trusted application, behind whatever firewalls and VPNs you've deployed.
A zero trust architecture assumes no implicit trust. Every request is verified. Session tokens are short-lived and continuously validated. Least-privilege access limits what an attacker can do even if they compromise a user session through XSS. This doesn't eliminate XSS, but it dramatically reduces the damage an attacker can inflict.
Real-World XSS Incidents That Should Keep You Up at Night
eBay (2015-2016): Researchers repeatedly found stored XSS vulnerabilities in eBay product listings. Attackers could embed malicious JavaScript in item descriptions, and every shopper who viewed the listing was a potential victim. Because eBay allowed active content in listings, the attack surface was enormous.
Fortnite (2019): Check Point Research discovered an XSS vulnerability in Epic Games' single sign-on system that could have allowed attackers to take over any player's account. The flaw existed in an old, unsecured page on an Epic Games subdomain. Millions of accounts were at risk before the fix was deployed.
British Airways (2018): As I mentioned at the top, a supply-chain compromise injected a credit card skimming script into BA's payment page. The script captured payment data in real time and exfiltrated it to attacker-controlled servers. The Magecart group behind the attack used script injection techniques rooted in the same principles as XSS.
These aren't obscure edge cases. These are household-name organizations with dedicated security teams. XSS finds a way.
A Quick XSS Security Checklist for Your Organization
If you want a practical starting point, here are the steps I recommend to every organization I work with:
- Audit all web applications for XSS vulnerabilities using both automated tools and manual testing.
- Implement strict input validation (allowlists, not blocklists) on every form and URL parameter.
- Apply context-aware output encoding on all rendered user data.
- Deploy Content Security Policy headers in enforcement mode.
- Set HTTPOnly and Secure flags on all session cookies.
- Require multi-factor authentication for all user accounts, especially administrators.
- Train developers on secure coding practices — specifically OWASP guidelines.
- Run regular phishing simulations to reduce the risk that employees click XSS-laden links.
- Adopt zero trust principles to limit lateral movement after any compromise.
- Establish an incident response plan that includes XSS exploitation scenarios.
XSS Isn't Going Away — But Your Exposure Can Shrink
Cross-site scripting has been in the OWASP Top 10 since its first publication in 2003. Twenty years later, it's still there. The tools and frameworks have improved, but the fundamental challenge remains: web applications process user input, and attackers will always try to abuse that trust relationship.
The organizations that minimize their XSS risk do three things consistently. They build security into their development process from day one. They test relentlessly. And they invest in training their people — developers and end users alike — to recognize and prevent these attacks.
Getting cross-site scripting explained in a blog post is step one. The real work starts when you take this knowledge back to your organization and apply it. Start with an audit of your web applications, enroll your team in security awareness training, and build the layered defenses that make XSS exploitation difficult, detectable, and survivable.