Cross-Site Scripting (XSS)
detect, understand, remediate
XSS allows attackers to inject malicious scripts into web pages viewed by other users, enabling session hijacking, credential theft, and defacement.
No credit card required. Free plan available forever.
What is cross-site scripting (XSS)?
Cross-site scripting (XSS) is a client-side code injection vulnerability that occurs when an application includes untrusted data in its web pages without proper validation or encoding. An attacker can inject malicious JavaScript that executes in the context of a victim's browser session, giving them access to cookies, session tokens, and any data the user can see or do on the page.
There are three primary variants. Reflected XSS occurs when user input is immediately returned in the response, typically via a URL parameter that is rendered without encoding. Stored XSS is more dangerous: the malicious payload is persisted (in a database, comment field, or profile) and served to every user who views the affected page. DOM-based XSS happens entirely in the browser when client-side JavaScript processes untrusted data and writes it into the DOM without sanitisation.
XSS enables session hijacking, credential theft, phishing overlays, keylogging, and website defacement. Because the malicious script runs with the same privileges as the legitimate application, victims have no way to distinguish the attack from normal site behaviour. XSS remains one of the most common web application vulnerabilities and is a primary target in every penetration test.
How it works
Find unencoded output
Attacker identifies a location where user-supplied input is reflected or rendered in the page without proper output encoding.
Inject JavaScript payload
A crafted payload is submitted (such as a script tag, event handler attribute, or JavaScript URI) designed to execute in the victim's browser.
Victim triggers execution
The victim visits the page containing stored XSS, or clicks a link containing reflected XSS. The browser parses the injected script as legitimate code.
Script executes in context
The malicious JavaScript runs with full access to the page, stealing session cookies, redirecting the user, injecting phishing forms, or exfiltrating data.
Common causes
Missing output encoding
Rendering user input in HTML, JavaScript, CSS, or URL contexts without applying the correct encoding for that context.
Use of innerHTML and dangerouslySetInnerHTML
Directly inserting user-controlled strings into the DOM using unsafe APIs that parse HTML instead of treating it as text.
User input in script contexts
Embedding user data inside inline script blocks, event handler attributes, or JavaScript template literals without escaping.
Absence of Content Security Policy
Without a CSP header, browsers have no restrictions on inline scripts or external script sources, making XSS exploitation trivial.
How to detect it
Automated detection
- SecPortal's authenticated scanner tests for reflected, stored, and DOM-based XSS across all discovered input points and parameters
- SecPortal's code scanner identifies unsafe rendering patterns such as innerHTML usage, template injection, and missing encoding functions
- Domain scanning checks for missing Content-Security-Policy headers that would mitigate XSS impact
Manual testing
- Inject script tags, event handlers (onerror, onload, onfocus), and JavaScript URIs into every input field and URL parameter
- Test different encoding contexts: HTML body, attribute values, JavaScript strings, CSS values, and URL parameters each require different payloads
- Check stored inputs (comments, profiles, file names) by injecting payloads and verifying whether they execute when other users view the content
How to fix it
Apply context-appropriate output encoding
Encode all user-controlled data before rendering. Use HTML entity encoding for HTML body, JavaScript escaping for script contexts, URL encoding for URLs, and CSS escaping for style contexts.
Implement a strict Content Security Policy
Deploy a CSP header that disables inline scripts (no unsafe-inline), restricts script sources to trusted origins, and uses nonces or hashes for any necessary inline scripts.
Use HTML sanitisation libraries
When rich text input is required, use a proven sanitisation library (e.g. DOMPurify) that strips dangerous elements and attributes while preserving safe formatting.
Set HttpOnly and Secure cookie flags
Mark session cookies as HttpOnly to prevent JavaScript access, and Secure to ensure they are only sent over HTTPS. This limits the impact of XSS by protecting session tokens.
Avoid innerHTML and unsafe DOM APIs
Use textContent or innerText instead of innerHTML. In React, avoid dangerouslySetInnerHTML. In other frameworks, use the built-in template escaping rather than raw HTML insertion.
Compliance impact
Related vulnerabilities
Detect XSS automatically
SecPortal tests for reflected, stored, and DOM-based XSS across all authenticated endpoints. Start scanning for free.
No credit card required. Free plan available forever.