Cross-site Scripting (Reflected)
- CAPEC 19
- CWE 79
- WASC 8
- OWASP 2017-A7
Cross-Site Scripting (XSS) is a client-side injection vulnerability that enables attackers to inject malicious scripts into web pages viewed by other users. When an application includes untrusted data in a web page without proper validation or escaping, an attacker can cause the victim’s browser to execute attacker-controlled JavaScript (or other client-side code), resulting in session hijacking, user impersonation, content manipulation, or the theft of sensitive data such as cookies, tokens and credentials.
There are three primary XSS types:
- Stored (persistent) XSS — malicious payloads are stored on the server (e.g., in a database, forum post, or comment) and are served to other users when they view the infected resource. This is often the most damaging because it can affect many users automatically.
- Reflected (non-persistent) XSS — the payload is included in a request (e.g., query parameter, form submission) and immediately reflected in the response. The attacker typically convinces a victim to follow a crafted link or submit a specially formed form.
- DOM-based XSS — the vulnerability occurs entirely in the client-side DOM: untrusted data is read by client-side code (e.g., location.hash, document.write, innerHTML) and used to modify the DOM in an unsafe way, without the server altering the content.
Why XSS happens:
- Failure to properly validate, filter, or encode untrusted input before placing it into a web page.
- Unsafe use of APIs that inject content into the DOM (e.g.,
innerHTML,document.write,eval). - Treating user data as HTML or script rather than data — no separation of content and executable context.
- Inconsistent or missing output-encoding for different contexts (HTML body, attribute, JavaScript, URL, CSS).
- Overly permissive content allow-lists for rich text editors or improper sanitizers.
Common consequences:
- Account takeover through theft of session cookies or tokens.
- Actions performed on behalf of users (CSRF-like effects) using stolen credentials.
- Phishing and social engineering by altering page content or UI elements.
- Exfiltration of data accessible in the browser (localStorage, DOM, page content).
- Drive-by distribution of malware or propagation of further attacks.
Detection and indicators:
- Presence of unescaped
<script>,on*attributes, or use ofinnerHTML/outerHTMLwith user data. - Automated scanners can detect many XSS patterns, but DOM-based issues often require manual review and browser instrumentation.
- Abnormal outbound connections from the client (to attacker-controlled domains) or unexpected script execution in user sessions.
- Code review focusing on output encoding, templating, and client-side DOM manipulation points.
Remediation
Mitigating XSS requires treating any untrusted input as data and applying context-aware output encoding, combined with appropriate input handling and secure UI practices.
Context-Aware Output Encoding
Encode output according to the context where it will appear:- HTML body: escape
<,>,&,"and'. - HTML attribute: additionally escape quotes and use proper quoting of attributes.
- JavaScript context: use JS string encoding or safely serialize data (e.g., JSON) and avoid injecting raw strings into script blocks.
- URL context: use percent-encoding for unsafe characters.
- CSS context: use CSS string escaping methods. Use well-tested encoding libraries (framework-provided or community-vetted) rather than hand-rolled escaping.
- HTML body: escape
Use Safe Templating and Framework Features
Prefer frameworks and templating engines that automatically escape output by default (e.g., React's JSX, Angular, Razor). Avoid constructs that bypass escaping (e.g.,dangerouslySetInnerHTML,ng-bind-htmlwithout sanitizer).Validate and Sanitize Input (When Appropriate)
Validate inputs for expected type, length and format. For rich text inputs, apply strict sanitization using a robust HTML sanitizer that allows only a minimal, well-audited set of tags and attributes. Keep sanitizer libraries up to date.Avoid Dangerous DOM APIs
On the client side, avoid APIs that directly interpret strings as HTML or code (e.g.,innerHTML,outerHTML,document.write,eval,setTimeout()with string arguments). Prefer text-setting APIs liketextContent,setAttribute, or DOM methods that create elements and set properties safely.Use Content Security Policy (CSP)
Implement a strong CSP to reduce the impact of XSS by restricting script sources, disallowingunsafe-inlinescripts, and enablingscript-srcnonces or hashes. CSP is a powerful mitigation but should not replace escaping and input handling.HTTP-only and Secure Cookies
Mark session cookiesHttpOnlyso they are not accessible to JavaScript, reducing the impact of session-stealing XSS attacks. Also useSecureand appropriateSameSiteattributes.Principle of Least Privilege in UI
Minimize sensitive data exposed in the browser, and avoid placing secrets or privileged tokens in client-side storage accessible to scripts.Safe Rich Text Handling
When allowing user-supplied HTML (e.g., WYSIWYG), sanitize and canonicalize on the server side, strip event handlers (on*), disallow dangerous protocols (e.g.,javascript:), and normalize attributes. Consider storing only sanitized HTML or a safe subset (or a structured representation like Markdown rendered server-side with safe renderer).Testing and Code Review
Include XSS scenarios in unit tests, integration tests, and security test plans. Use automated scanners, manual penetration testing, and DOM-focused testing tools to catch client-side vulnerabilities.User Education and Monitoring
Educate developers about XSS risks and secure patterns. Monitor client-side errors and suspicious activity that may indicate XSS exploitation attempts.