Cross-site scripting (XSS) is a web security vulnerability where an attacker injects malicious scripts into web pages viewed by other users. When a victim's browser executes the injected script, the attacker can steal session tokens, redirect users to malicious sites, deface web content, or perform actions on behalf of the victim. XSS exploits the trust a user's browser places in the content delivered by your application.
Cross-site scripting, or XSS, is an attack where someone injects malicious JavaScript into your web application that then executes in another user's browser. The name is misleading (there's no "cross-site" component in most attacks), but the impact is concrete: the attacker's script runs with the same permissions as your legitimate application code.
When a user's browser loads a page from your application, it trusts everything on that page. If an attacker can get their script onto your page, the browser treats it as part of your application. That script can then:
There are three main variants, each with a different attack mechanism:
Cross-site scripting is consistently the most commonly discovered web vulnerability class. MITRE CWE classifies it as CWE-79 (Improper Neutralization of Input During Web Page Generation), and the OWASP Top 10:2025 includes it under the Injection category. HackerOne reports that XSS accounts for roughly 20% of all vulnerabilities submitted to bug bounty programs, making it the #1 most commonly reported vulnerability type on their platform.
Here's why startups should care:
dangerouslySetInnerHTML, Vue's v-html directive, Angular's bypassSecurityTrust methods. The moment a developer uses one of these with user-controlled data, the framework's protections are bypassed. AI coding tools are particularly prone to using these unsafe patterns.XSS prevention comes down to one principle: never trust user input, and always encode output.
dangerouslySetInnerHTML and its equivalents as security-sensitive code that requires review.dangerouslySetInnerHTML). Dynamic testing sends XSS payloads against your running application to find reflected and stored XSS that code analysis can miss.Fencer's SAST scanning detects XSS-prone code patterns in your repositories, including unsafe rendering methods and missing output encoding. Fencer's DAST scanning tests your running application with XSS payloads to find reflected and stored XSS vulnerabilities that are actually exploitable. Findings appear inline in your pull requests so developers can fix XSS before it ships, rather than discovering it in a pen test months later.
Modern frameworks like React, Vue, and Angular provide significant XSS protection through automatic output encoding. React escapes values embedded in JSX by default, and Vue escapes content in template expressions. However, this protection has limits. Any use of dangerouslySetInnerHTML (React), v-html (Vue), or bypassSecurityTrustHtml (Angular) with user-controlled data bypasses the framework's protections entirely. Third-party libraries that manipulate the DOM directly can also introduce XSS. Treat your framework's defaults as a strong foundation, not a guarantee, and scan your code for unsafe rendering patterns.
Both are injection attacks, but they target different layers. SQL injection targets your server's database by injecting malicious database queries through user input. XSS targets your users' browsers by injecting malicious JavaScript through your application's output. SQL injection compromises your data. XSS compromises your users. The defenses are different too: SQL injection is prevented by parameterized queries (separating commands from data on the server), while XSS is prevented by output encoding (separating code from data in the browser). Both are in the OWASP Top 10 Injection category, and most applications should be testing for both.
Yes, and in some ways more so. Single-page applications (SPAs) that handle routing and rendering in the browser are particularly susceptible to DOM-based XSS, where the vulnerability exists entirely in client-side JavaScript and never touches the server. Traditional server-side XSS protections (like WAFs) can't catch DOM-based XSS because the malicious payload never appears in a server request. If your SPA reads data from the URL, query parameters, or the hash fragment and writes it to the page without sanitization, you have a DOM-based XSS vulnerability that server-side scanning will miss. DAST tools that execute JavaScript and test the rendered DOM are essential for catching these.