用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/CyberStrikeus/CyberStrike --skill wstg-clnt-12命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
macOS post-exploitation for credential harvesting, DTrace monitoring, TCC bypass, and stealth operations via native tools
Windows userland post-exploitation for credential harvesting, monitoring, AMSI/ETW bypass, and stealth operations
Kubernetes post-exploitation for container escape, secret extraction, RBAC abuse, and cluster persistence
基于 SOC 职业分类
正在显示 SKILL.md
| name | wstg-clnt-12 |
| description | Testing Browser Storage |
| category | client-side |
| owasp_id | WSTG-CLNT-12 |
| 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-12
Testing Browser Storage
Browser storage mechanisms (localStorage, sessionStorage, IndexedDB, cookies) can store sensitive data client-side. Vulnerabilities occur when sensitive information is stored insecurely, accessible to XSS attacks, or persists longer than necessary. Testing ensures proper data protection and lifecycle management.
// Browser console - Enumerate all storage
// Check localStorage
console.log("=== localStorage ===")
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i)
const value = localStorage.getItem(key)
console.log(`${key}: ${value.substring(0, 100)}...`)
}
// Check sessionStorage
console.log("\n=== sessionStorage ===")
( i = ; i < .; i++) {
key = .(i)
value = .(key)
.()
}
.()
..().( {
.(cookie.())
})
.()
indexedDB.().( {
dbs.( .())
})
#!/usr/bin/env python3
"""
Browser Storage Security Analyzer
Uses Selenium to analyze client-side storage
"""
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import json
import time
class BrowserStorageTester:
def __init__(self, url):
self.url = url
self.findings = []
self.setup_browser()
def setup_browser(self):
"""Setup headless Chrome"""
options = Options()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
self.driver = webdriver.Chrome(options=options)
def analyze_storage(self):
"""Analyze all browser storage"""
print(f"[*] Analyzing storage for {self.url}")
self.driver.get(self.url)
time.sleep(3) # Wait for page load
# Get localStorage
local_storage = self.driver.execute_script("""
let items = {};
for (let i = 0; i < localStorage.length; i++) {
let key = localStorage.key(i);
items[key] = localStorage.getItem(key);
}
return items;
""")
# Get sessionStorage
session_storage = self.driver.execute_script("""
let items = {};
for (let i = 0; i < sessionStorage.length; i++) {
let key = sessionStorage.key(i);
items[key] = sessionStorage.getItem(key);
}
return items;
""")
# Get cookies
cookies = self.driver.get_cookies()
return {
'localStorage': local_storage,
'sessionStorage': session_storage,
'cookies': cookies
}
def check_sensitive_data(self, storage_data):
"""Check for sensitive data patterns"""
print("\n[*] Checking for sensitive data...")
sensitive_patterns = [
('password', 'Password'),
('token', 'Authentication Token'),
('api_key', 'API Key'),
('apikey', 'API Key'),
('secret', 'Secret'),
('credit', 'Credit Card'),
('ssn', 'Social Security'),
('session', 'Session Data'),
('auth', 'Authentication Data'),
('bearer', 'Bearer Token'),
('jwt', 'JWT Token'),
('private', 'Private Data'),
]
# Check localStorage
for key, value in storage_data.get('localStorage', {}).items():
for pattern, description in sensitive_patterns:
if pattern.lower() in key.lower() or pattern.lower() in str(value).lower():
print(f"[VULN] Sensitive data in localStorage: {key}")
self.findings.append({
"location": "localStorage",
"key": key,
"issue": f"Potential {description} exposed",
"severity": "High"
})
# Check sessionStorage
for key, value in storage_data.get('sessionStorage', {}).items():
for pattern, description in sensitive_patterns:
if pattern.lower() in key.lower() or pattern.lower() in str(value).lower():
print(f"[WARN] Sensitive data in sessionStorage: {key}")
self.findings.append({
"location": "sessionStorage",
"key": key,
"issue": f"Potential {description} exposed",
"severity": "Medium"
})
# Check cookies
for cookie in storage_data.get('cookies', []):
name = cookie.get('name', '')
for pattern, description in sensitive_patterns:
if pattern.lower() in name.lower():
if not cookie.get('httpOnly'):
print(f"[VULN] Sensitive cookie without HttpOnly: {name}")
self.findings.append({
"location": "cookie",
"key": name,
"issue": f"{description} cookie without HttpOnly",
"severity": "High"
})
if not cookie.get('secure'):
print(f"[VULN] Sensitive cookie without Secure: {name}")
self.findings.append({
"location": "cookie",
"key": name,
"issue": f"{description} cookie without Secure flag",
"severity": "Medium"
})
def check_cookie_attributes(self, storage_data):
"""Check cookie security attributes"""
print("\n[*] Checking cookie attributes...")
for cookie in storage_data.get('cookies', []):
name = cookie.get('name', '')
issues = []
if not cookie.get('httpOnly'):
issues.append("Missing HttpOnly")
if not cookie.get('secure'):
issues.append("Missing Secure")
if cookie.get('sameSite', '').lower() not in ['strict', 'lax']:
issues.append("Missing/Weak SameSite")
if issues:
print(f"[WARN] Cookie '{name}': {', '.join(issues)}")
for issue in issues:
self.findings.append({
"location": "cookie",
"key": name,
"issue": issue,
"severity": "Medium" if "HttpOnly" in issue else "Low"
})
def test_xss_access(self):
"""Test if XSS could access storage"""
print("\n[*] Testing XSS accessibility to storage...")
# Execute XSS-like script to test access
result = self.driver.execute_script("""
let accessible = {
localStorage: false,
sessionStorage: false,
cookies: false
};
try {
localStorage.setItem('xss_test', 'test');
localStorage.removeItem('xss_test');
accessible.localStorage = true;
} catch(e) {}
try {
sessionStorage.setItem('xss_test', 'test');
sessionStorage.removeItem('xss_test');
accessible.sessionStorage = true;
} catch(e) {}
try {
accessible.cookies = document.cookie.length > 0 || true;
} catch(e) {}
return accessible;
""")
print(f" localStorage accessible via JS: {result.get('localStorage')}")
print(f" sessionStorage accessible via JS: {result.get('sessionStorage')}")
print(f" Cookies accessible via JS: {result.get('cookies')}")
return result
def generate_report(self):
"""Generate security report"""
print("\n" + "="*50)
print("BROWSER STORAGE SECURITY REPORT")
print("="*50)
if not self.findings:
print("\nNo significant issues found.")
else:
high = [f for f in self.findings if f['severity'] == 'High']
medium = [f for f in self.findings if f['severity'] == 'Medium']
low = [f for f in self.findings if f['severity'] == 'Low']
if high:
print(f"\n[HIGH SEVERITY] ({len(high)} issues)")
for f in high:
print(f" - {f['location']}/{f['key']}: {f['issue']}")
if medium:
print(f"\n[MEDIUM SEVERITY] ({len(medium)} issues)")
for f in medium:
print(f" - {f['location']}/{f['key']}: {f['issue']}")
if low:
print(f"\n[LOW SEVERITY] ({len(low)} issues)")
for f in low:
print(f" - {f['location']}/{f['key']}: {f['issue']}")
def run_tests(self):
"""Run all tests"""
try:
storage_data = self.analyze_storage()
print("\n[*] Storage Contents:")
print(f" localStorage entries: {len(storage_data.get('localStorage', {}))}")
print(f" sessionStorage entries: {len(storage_data.get('sessionStorage', {}))}")
print(f" Cookies: {len(storage_data.get('cookies', []))}")
self.check_sensitive_data(storage_data)
self.check_cookie_attributes(storage_data)
self.test_xss_access()
self.generate_report()
finally:
self.driver.quit()
# Usage
tester = BrowserStorageTester("https://target.com")
tester.run_tests()
// Analyze IndexedDB contents
async function analyzeIndexedDB() {
const databases = await indexedDB.databases()
for (const dbInfo of databases) {
console.log(`\n=== Database: ${dbInfo.name} ===`)
const request = indexedDB.open(dbInfo.name)
request.onsuccess = function (event) {
const db = event.target.result
const storeNames = db.objectStoreNames
console.log("Object Stores:", Array.from(storeNames))
for (const storeName of storeNames) {
const transaction = db.transaction(storeName, "readonly")
const store = transaction.objectStore(storeName)
const getAllRequest = store.getAll()
getAllRequest.onsuccess = function () {
console.log(`\nStore: ${storeName}`)
console.log("Records:", getAllRequest.result.length)
// Check for sensitive data
getAllRequest.result.forEach((record, i) => {
const str = JSON.stringify(record)
if (str.match(/password|token|secret|key|auth/i)) {
console.log(`[!] Potential sensitive data in record ${i}`)
}
})
}
}
}
}
}
analyzeIndexedDB()
#!/bin/bash
TARGET="https://target.com"
# Fetch and analyze cookies
echo "[*] Analyzing cookies for $TARGET"
curl -sI "$TARGET" | grep -i "set-cookie" | while read -r line; do
echo ""
echo "Cookie: $line"
# Check security attributes
if ! echo "$line" | grep -qi "httponly"; then
echo " [!] Missing HttpOnly"
fi
if ! echo "$line" | grep -qi "secure"; then
echo " [!] Missing Secure"
fi
if ! echo "$line" | grep -qi "samesite"; then
echo " [!] Missing SameSite"
fi
done
| Tool | Purpose |
|---|---|
| Browser DevTools (Application tab) | View all storage |
| EditThisCookie | Cookie editor extension |
| Selenium/Puppeteer | Automated storage analysis |
| Burp Suite | Cookie analysis |
// SECURE: Don't store sensitive data in localStorage
// Use server-side sessions instead
// If client storage is needed, encrypt sensitive data
class SecureStorage {
constructor(encryptionKey) {
this.key = encryptionKey;
}
async encrypt(data) {
const encoder = new TextEncoder();
const encodedData = encoder.encode(JSON.stringify(data));
const cryptoKey = await crypto.subtle.importKey(
'raw',
encoder.encode(this.key),
{ name: 'AES-GCM' },
false,
['encrypt']
);
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv },
cryptoKey,
encodedData
);
return {
iv: Array.from(iv),
data: Array.from(new Uint8Array(encrypted))
};
}
async setItem(key, value) {
const encrypted = await this.encrypt(value);
sessionStorage.setItem(key, JSON.stringify(encrypted));
}
}
// SECURE: Set proper cookie attributes
// Server-side (Python/Flask)
from flask import make_response
@app.route('/login', methods=['POST'])
def login():
response = make_response(redirect('/dashboard'))
response.set_cookie(
'session_id',
value=generate_session_id(),
secure=True, # HTTPS only
httponly=True, # No JavaScript access
samesite='Strict', # No cross-site requests
max_age=3600, # 1 hour expiry
path='/',
domain='.example.com'
)
return response
// SECURE: Clear storage on logout
function secureLogout() {
// Clear all storage
localStorage.clear();
sessionStorage.clear();
// Clear IndexedDB
indexedDB.databases().then(dbs => {
dbs.forEach(db => indexedDB.deleteDatabase(db.name));
});
// Clear cookies (server should also invalidate)
document.cookie.split(';').forEach(cookie => {
const name = cookie.split('=')[0].trim();
document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/`;
});
// Redirect to login
window.location.href = '/login';
}
| Finding | CVSS | Severity |
|---|---|---|
| Credentials in localStorage | 7.5 | High |
| Session token in localStorage | 7.5 | High |
| Sensitive cookie without HttpOnly | 6.1 | Medium |
| Missing Secure flag on sensitive cookie | 5.3 | Medium |
| PII in browser storage | 5.3 | Medium |
| CWE ID | Title |
|---|---|
| CWE-922 | Insecure Storage of Sensitive Information |
| CWE-312 | Cleartext Storage of Sensitive Information |
| CWE-1004 | Sensitive Cookie Without 'HttpOnly' Flag |
| CWE-614 | Sensitive Cookie in HTTPS Session Without 'Secure' Attribute |
[ ] localStorage analyzed
[ ] sessionStorage analyzed
[ ] IndexedDB databases enumerated
[ ] Cookie attributes checked
[ ] Sensitive data patterns searched
[ ] XSS accessibility tested
[ ] Data persistence after logout tested
[ ] Findings documented