September 7, 2026
Cross-Site Scripting (XSS): A Practical Guide for Web VAPT
Introduction
By Sahil mandave
5 min read
Introduction
Cross-Site Scripting, commonly known as XSS, is one of the most well-known vulnerabilities in Web Application Security.
XSS occurs when an application accepts attacker-controlled input and places it into a web page without properly validating or encoding it. As a result, a browser may interpret the injected content as executable code instead of ordinary data.
From a VAPT perspective, understanding XSS is important because it helps security testers identify weaknesses in input handling, output encoding, session security, and application architecture.
In this article, we will understand:
- What XSS is
- How XSS works
- Types of XSS
- Reflected XSS
- Stored XSS
- DOM-based XSS
- How to identify XSS during VAPT
- Safe testing methodology
- Impact of XSS
- Common bypass concepts
- Remediation
- Common mistakes during testing
- Practical learning resources
What is XSS?
Cross-Site Scripting (XSS) is a client-side injection vulnerability where untrusted data is interpreted by the victim's browser as executable content.
A simple example is an application that takes a user's name and displays:
Welcome, SahilWelcome, SahilIf the application directly inserts untrusted input into the HTML without proper output encoding, an attacker may be able to inject HTML or JavaScript.
Conceptually:
User Input
โ
Web Application
โ
Unsafe Output
โ
Victim's Browser
โ
Injected Code InterpretedUser Input
โ
Web Application
โ
Unsafe Output
โ
Victim's Browser
โ
Injected Code InterpretedThe key problem is not simply that an application accepts special characters. The real issue is that untrusted data reaches a browser context where it is interpreted as code or markup.
Why Does XSS Happen?
XSS generally occurs because an application does not properly handle untrusted input before placing it into an executable browser context.
Common contributing factors include:
- Missing output encoding
- Improper HTML sanitization
- Unsafe DOM manipulation
- Incorrect use of dangerous JavaScript APIs
- Mixing trusted and untrusted data
- Improper handling of different browser contexts
For example, consider:
<div>USERNAME</div><div>USERNAME</div>If USERNAME comes directly from an attacker-controlled parameter and is not safely encoded, the application may unintentionally allow markup to be interpreted by the browser.
A secure application should treat the value as data, not executable markup.
Types of XSS
There are three major categories of XSS:
- Reflected XSS
- Stored XSS
- DOM-based XSS
Although all three involve unsafe execution in a browser, the way the malicious input reaches the execution point is different.
1. Reflected XSS
Reflected XSS occurs when malicious input is included in an HTTP request and is immediately reflected in the application's response.
For example:
https://example.com/search?q=USER_INPUThttps://example.com/search?q=USER_INPUTThe application might display:
Search results for: USER_INPUTSearch results for: USER_INPUTIf the application does not properly encode the value, attacker-controlled content may be interpreted by the browser.
Basic Flow
Attacker
โ
Crafted Request
โ
Web Application
โ
Input Reflected in Response
โ
Victim Browser
โ
Browser Interprets Unsafe ContentAttacker
โ
Crafted Request
โ
Web Application
โ
Input Reflected in Response
โ
Victim Browser
โ
Browser Interprets Unsafe ContentWhere to Look for Reflected XSS
During testing, look for parameters such as:
q=
search=
query=
name=
message=
redirect=
return=
error=
page=
id=q=
search=
query=
name=
message=
redirect=
return=
error=
page=
id=These are only examples. Any user-controlled parameter can potentially become relevant depending on how the application processes it.
How to Test Reflected XSS
A safe testing methodology is:
Step 1: Identify Input Points
Look for:
- URL parameters
- Form fields
- Search boxes
- Error messages
- HTTP headers where applicable
- API parameters
- POST body parameters
Step 2: Use a Harmless Marker
Start with a unique test string:
XSS_TEST_12345XSS_TEST_12345Send the request and check whether the value appears in the response.
Step 3: Identify the Context
If the value is reflected, determine where it appears.
For example:
<div>XSS_TEST_12345</div><div>XSS_TEST_12345</div>or:
<input value="XSS_TEST_12345"><input value="XSS_TEST_12345">or:
var search = "XSS_TEST_12345";var search = "XSS_TEST_12345";The context is extremely important because different contexts require different defensive handling.
Step 4: Validate Safely
In an authorized test environment, use a harmless proof of concept appropriate to the context rather than attempting to steal credentials or session information.
The goal of a VAPT test is to demonstrate that attacker-controlled input can cross a security boundary, not to compromise real users.
2. Stored XSS
Stored XSS is generally more concerning because the malicious input is stored by the application and later served to other users.
Common storage locations include:
- Database records
- Comments
- User profiles
- Support tickets
- Messages
- Reviews
- Forum posts
- Product descriptions
Example Flow
Attacker
โ
Submit Malicious Input
โ
Application Stores Input
โ
Victim Opens Affected Page
โ
Stored Input Returned
โ
Browser Interprets ItAttacker
โ
Submit Malicious Input
โ
Application Stores Input
โ
Victim Opens Affected Page
โ
Stored Input Returned
โ
Browser Interprets ItUnlike reflected XSS, the attacker may not need to send a specially crafted URL to every victim.
Example Scenario
Imagine a website containing a comment feature:
User: Sahil
Comment:
Great application!User: Sahil
Comment:
Great application!The application stores the comment and displays it to everyone.
If the application stores attacker-controlled markup without appropriate sanitization or encoding, the stored content could potentially execute when another user views the page.
This is why stored XSS can have a broader impact.
Testing Stored XSS
During an authorized assessment:
Step 1
Identify fields that are stored by the application.
Examples:
Comments
Profile information
Reviews
Messages
Tickets
DescriptionsComments
Profile information
Reviews
Messages
Tickets
DescriptionsStep 2
Submit a unique harmless test value.
STORED_XSS_TEST_987STORED_XSS_TEST_987Step 3
Reload the page or access it from another test account.
Step 4
Determine whether the input is:
- Stored
- Reflected
- HTML encoded
- Sanitized
- Rendered in a browser context
Step 5
If the application is vulnerable, demonstrate the issue using a controlled proof of concept.
3. DOM-Based XSS
DOM-based XSS is different because the vulnerability can occur entirely within client-side JavaScript.
The server may return a completely normal response.
The problem happens when JavaScript takes attacker-controlled data and inserts it into an unsafe DOM sink.
For example:
document.getElementById("output").innerHTML = userInput;document.getElementById("output").innerHTML = userInput;If userInput is attacker-controlled and is not safely handled, the browser may interpret it as HTML.
DOM XSS Flow
Attacker-Controlled Input
โ
JavaScript
โ
DOM Sink
โ
Browser
โ
Unsafe InterpretationAttacker-Controlled Input
โ
JavaScript
โ
DOM Sink
โ
Browser
โ
Unsafe InterpretationCommon Sources in DOM XSS
Potential sources include:
location
location.href
location.search
location.hash
document.URL
document.referrerlocation
location.href
location.search
location.hash
document.URL
document.referrerThese should not automatically be considered vulnerable.
The important question is:
Does attacker-controlled data flow from a source into a dangerous sink without appropriate protection?
Common DOM XSS Sinks
Examples of potentially dangerous sinks include:
innerHTML
outerHTML
document.write()
eval()innerHTML
outerHTML
document.write()
eval()Other JavaScript APIs may also become dangerous depending on how they are used.
For example:
element.innerHTML = userInput;element.innerHTML = userInput;is significantly different from safely assigning text content:
element.textContent = userInput;element.textContent = userInput;The latter treats the value as text rather than HTML.
XSS Contexts
One of the most important concepts in XSS testing is context.
The same input may behave differently depending on where the application places it.
Common contexts include:
HTML Context
<div>USER_INPUT</div><div>USER_INPUT</div>HTML Attribute Context
<input value="USER_INPUT"><input value="USER_INPUT">JavaScript Context
var name = "USER_INPUT";var name = "USER_INPUT";URL Context
<a href="USER_INPUT">Click</a><a href="USER_INPUT">Click</a>CSS Context
<div style="USER_INPUT"><div style="USER_INPUT">Each context requires appropriate defensive controls.
Therefore, simply searching for an input string in the response is not enough.
How I Approach XSS During VAPT
A structured methodology makes testing more effective.
Phase 1 โ Reconnaissance
Identify:
- Application functionality
- Input fields
- Parameters
- Forms
- Search functionality
- Comments
- User profile fields
- API endpoints
- Client-side JavaScript
Phase 2 โ Input Discovery
Identify all locations where users can influence application behavior.
For example:
GET parameters
POST parameters
JSON parameters
Form fields
Path parameters
Headers
Cookies
Client-side URL fragmentsGET parameters
POST parameters
JSON parameters
Form fields
Path parameters
Headers
Cookies
Client-side URL fragmentsPhase 3 โ Reflection Testing
Use a unique marker:
TEST_XSS_123TEST_XSS_123Then determine:
- Is it reflected?
- Where is it reflected?
- Is it HTML encoded?
- Is it JavaScript encoded?
- Is it stored?
- Is it inserted into the DOM?
Phase 4 โ Context Identification
Determine the exact browser context.
For example:
<p>INPUT</p><p>INPUT</p>is different from:
<input value="INPUT"><input value="INPUT">and:
var x = "INPUT";var x = "INPUT";This step is critical for understanding whether the input can cross from data into executable content.
Phase 5 โ Proof of Concept
For authorized testing, demonstrate the vulnerability using the least harmful proof necessary.
Avoid collecting:
- Real credentials
- Session tokens
- Personal information
- Cookies belonging to other users
The purpose of the POC is to prove the security issue safely.
XSS Testing Using Burp Suite
Burp Suite is one of the most useful tools for Web VAPT.
A typical workflow is:
Browser
โ
Burp Proxy
โ
Web ApplicationBrowser
โ
Burp Proxy
โ
Web ApplicationUsing Burp Repeater
- Capture a request.
- Send it to Repeater.