Phy Cors Audit
CORS(跨域资源共享)配置错误审核员。使用精心设计的 Origin 标头探测任何 API 端点,以检测最危险的 CORS 漏洞 - 反映任意来源(任何 Attacker.com 都获得 CORS 批准)、Access-Control-Allow-Credentials:true 并带有通配符 ACAO、允许 null-Origin(iframe/file:// 绕过)、子域正则表达式绕过(evil.myapp.com 通行证)、缺少 Vary:Origin(CDN 缓存中毒)以及允许的预检响应。还扫描源代码以查找不安全的 CORS 中间件模式(Express/FastAPI/Go/Rails/Django/Spring)。为您的特定堆栈生成正确的 CORS 配置。通过curl 适用于任何实时URL — 零外部API。在“CORS 错误”、“CORS 错误配置”、“Access-Control-Allow-Origin”、“cors 策略”、“预检”、“cors 阻止”、“/cors-audit”上触发。
安装 / 下载方式
TotalClaw CLI推荐
totalclaw install totalclaw:phy041~phy-cors-auditcURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Aphy041~phy-cors-audit/file -o phy-cors-audit.mdGit 仓库获取源码
git clone https://github.com/openclaw/skills/commit/e535d075cc37190b1c46932a60278df197f5ec1c## 概述(中文)
CORS(跨域资源共享)配置错误审核员。使用精心设计的 Origin 标头探测任何 API 端点,以检测最危险的 CORS 漏洞 - 反映任意来源(任何 Attacker.com 都获得 CORS 批准)、Access-Control-Allow-Credentials:true 并带有通配符 ACAO、允许 null-Origin(iframe/file:// 绕过)、子域正则表达式绕过(evil.myapp.com 通行证)、缺少 Vary:Origin(CDN 缓存中毒)以及允许的预检响应。还扫描源代码以查找不安全的 CORS 中间件模式(Express/FastAPI/Go/Rails/Django/Spring)。为您的特定堆栈生成正确的 CORS 配置。通过curl 适用于任何实时URL — 零外部API。在“CORS 错误”、“CORS 错误配置”、“Access-Control-Allow-Origin”、“cors 策略”、“预检”、“cors 阻止”、“/cors-audit”上触发。
## 原文
# CORS Audit
`Access to fetch at 'https://api.myapp.com' from origin 'https://evil.com' has been set with CORS policy: No 'Access-Control-Allow-Origin'`
Then you add `Access-Control-Allow-Origin: *` and it works. Except now your API accepts requests from every site on the internet, with every user's credentials, if you forgot to check the credentials flag.
This skill probes your CORS configuration with crafted Origin headers, finds the misconfigurations that let attackers run authenticated cross-origin requests against your users, and generates the correct allow-list config for your stack.
**Works against any live URL via curl. Scans Express/FastAPI/Go/Rails/Django source. Zero external API.**
---
## Trigger Phrases
- "CORS error", "CORS blocked", "CORS not working"
- "CORS misconfiguration", "cors security"
- "Access-Control-Allow-Origin", "ACAO"
- "cors policy", "preflight OPTIONS"
- "cors wildcard", "cors credentials"
- "/cors-audit"
---
## How to Provide Input
```bash
# Option 1: Probe a live API endpoint
/cors-audit https://api.myapp.com/users
# Option 2: Probe with specific origin
/cors-audit https://api.myapp.com --origin https://evil.com
# Option 3: Full probe battery (all known bypasses)
/cors-audit https://api.myapp.com --full
# Option 4: Scan source code for CORS misconfigurations
/cors-audit --scan src/
# Option 5: Generate correct CORS config for your stack
/cors-audit --generate express --allowed-origins https://myapp.com,https://staging.myapp.com
# Option 6: CI mode (exit 1 on critical findings)
/cors-audit https://api.myapp.com --ci
# Option 7: Audit multiple endpoints at once
/cors-audit --endpoints /api/users,/api/orders,/api/admin --base https://api.myapp.com
```
---
## Step 1: Probe CORS Configuration
```python
import subprocess
import re
from dataclasses import dataclass, field
from typing import Optional
from urllib.parse import urlparse
@dataclass
class CorsProbeResult:
probe_name: str
origin_sent: str
acao: Optional[str] # Access-Control-Allow-Origin
acac: Optional[str] # Access-Control-Allow-Credentials
acam: Optional[str] # Access-Control-Allow-Methods
acah: Optional[str] # Access-Control-Allow-Headers
vary: Optional[str] # Vary header
status_code: int
is_vulnerable: bool
severity: str
issue: str
fix: str
def probe_cors(url: str, origin: str, method: str = 'GET') -> dict:
"""Send a single CORS probe and return response headers."""
result = subprocess.run(
['curl', '-sI', '-X', method, url,
'-H', f'Origin: {origin}',
'-H', 'Content-Type: application/json',
'--max-time', '10',
'--user-agent', 'CorsAuditor/1.0'],
capture_output=True, text=True
)
headers = {}
status_code = 200
for line in result.stdout.splitlines():
if line.startswith('HTTP/'):
try:
status_code = int(line.split()[1])
except (IndexError, ValueError):
pass
elif ':' in line:
key, _, value = line.partition(':')
headers[key.strip().lower()] = value.strip()
return {'headers': headers, 'status_code': status_code, 'raw': result.stdout}
def run_cors_battery(url: str) -> list[CorsProbeResult]:
"""
Run the full battery of CORS probes against a URL.
Tests all known CORS misconfiguration patterns.
"""
parsed = urlparse(url)
base_domain = parsed.netloc # e.g. api.myapp.com
# Derive legitimate origin (for baseline)
legitimate_origin = f'{parsed.scheme}://{base_domain.replace("api.", "")}'
# Build the probe set
probes = [
{
'name': 'arbitrary_origin_evil',
'origin': 'https://evil.com',
'description': 'Random attacker origin',
},
{
'name': 'null_origin',
'origin': 'null',
'description': 'null origin (file://, sandboxed iframe)',
},
{
'name': 'subdomain_bypass',
'origin': f'https://evil.{base_domain}',
'description': f'Subdomain of target: evil.{base_domain}',
},
{
'name': 'prefix_bypass',
'origin': f'https://{base_domain}.evil.com',
'description': f'Domain that contains target as prefix: {base_domain}.evil.com',
},
{
'name': 'http_downgrade',
'origin': f'http://{base_domain}',
'description': f'HTTP version of same domain: http://{base_domain}',
},
{
'name': 'legitimate_origin',
'origin': legitimate_origin,
'description': f'Legitimate origin: {legitimate_origin}',
},
{
'name': 'wildcard_check',
'origin': 'https://completely-unrelated.com',
'description': 'Completely unrelated domain',
},
]
results = []
for probe in probes:
resp = probe_cors(url, probe['origin'])
headers = resp['headers']
acao = headers.get('access-control-allow-origin')
acac = headers.get('access-control-allow-credentials', '').lower()
vary = headers.get('vary', '')
# Analyze the response
is_vulnerable = False
severity = 'INFO'
issue = ''
fix = ''
if not acao:
# No CORS headers — either not configured or blocked
if probe['name'] == 'legitimate_origin':
issue = 'No CORS headers returned for legitimate origin'
severity = 'INFO'
else:
issue = 'Request blocked (no ACAO header) ✅'
severity = 'PASS'
elif acao == '*':
if acac == 'true':
# IMPOSSIBLE combination per spec, but some servers misconfigure this
is_vulnerable = True
severity = 'CRITICAL'
issue = 'Access-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true — browsers reject this, but some HTTP clients do not'
fix = 'Never use wildcard with credentials. Specify exact origins: Access-Control-Allow-Origin: https://myapp.com'
else:
if probe['name'] in ('arbitrary_origin_evil', 'wildcard_check'):
severity = 'HIGH'
is_vulnerable = True
issue = 'Wildcard ACAO (*) — any origin can make unauthenticated cross-origin requests'
fix = 'Replace * with an explicit allowlist. Wildcard is safe only for fully public, unauthenticated APIs.'
else:
severity = 'MEDIUM'
issue = 'Wildcard ACAO — acceptable only if API requires no authentication'
fix = 'Confirm this endpoint has no authentication. If it does, restrict ACAO to specific origins.'
elif acao == probe['origin']:
# Origin is reflected — check if this is intentional
if probe['name'] == 'legitimate_origin':
severity = 'PASS'
issue = f'Origin correctly reflected for legitimate origin ✅'
# Check for Vary: Origin
if 'origin' not in vary.lower():
severity = 'MEDIUM'
is_vulnerable = True
issue = 'ACAO reflects Origin but Vary: Origin missing — CDN/proxy may cache and serve wrong CORS response'
fix = 'Add Va