Skip to content

feat(protect): cors_reflected match type for CORS-misconfiguration detection - #110

Merged
patchstackdave merged 1 commit into
mainfrom
feat/cors-reflection-detection
Aug 12, 2026
Merged

feat(protect): cors_reflected match type for CORS-misconfiguration detection#110
patchstackdave merged 1 commit into
mainfrom
feat/cors-reflection-detection

Conversation

@patchstackdave

Copy link
Copy Markdown
Contributor

Why

The third origin-comparison capability unlocked by threading the request into the response phase (#106), after cross_origin (CSRF) and off_origin (open-redirect, #109). CORS misconfiguration — a response that reflects the caller's Origin and allows credentials — lets any site read the authenticated response; a common, high-impact bug in AI-built APIs.

What

New cors_reflected response-phase match type (dispatched like cross_origin, needs the whole resolver):

  • Matches (→ action: block) when Access-Control-Allow-Credentials: true AND the Access-Control-Allow-Origin either is * or echoes the request Origin (so every origin is allowed).
  • A fixed allowlisted origin, reflection without credentials, or no CORS headers → not flagged. Can't false-positive without the signal.
{ "phase": "response", "category": "cors", "action": "block",
  "when": { "path": "/api/*" },
  "rule_v2": [{ "match": { "type": "cors_reflected" } }] }

Blocking withholds the response, preventing the cross-origin read. Not a default — authored and route-scoped. (A future header-mutation action — strip ACAC / pin ACAO — would be a gentler mitigation than a full block; noted for later.)

Tests

tests/protect/cors-reflection.test.ts — 6: reflected-origin + credentials blocked, wildcard + credentials blocked, fixed allowlist allowed, reflection-without-credentials allowed, no-CORS-headers allowed, when route scope. 632 pass; typecheck clean.

🤖 Generated with Claude Code

@coderbuds

coderbuds Bot commented Aug 12, 2026

Copy link
Copy Markdown

Well-structured CORS misconfiguration detection feature with comprehensive tests.

🎯 Quality: 100% Elite · 📦 Size: Small

📈 This month: Your 50th PR — above team average · Averaging Excellent

See how your team is trending →

@patchstackdave

Copy link
Copy Markdown
Contributor Author

/review

…tection

Add a `cors_reflected` response-phase primitive (dispatched like cross_origin/off_origin): true
(→ block) when a response allows credentials AND either uses `Access-Control-Allow-Origin: *` or
reflects the caller's own Origin — the combination that lets any malicious site read the
authenticated response. A fixed allowlisted origin, or reflection without credentials, is not
flagged. Uses the request Origin threaded into the response phase (#106).

Third origin-comparison primitive after cross_origin (CSRF) and off_origin (open-redirect). Not a
default; authored + route-scoped via `when`. +6 tests; 632 pass; typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@patchstackdave
patchstackdave force-pushed the feat/cors-reflection-detection branch from 36d27b0 to a1d4f98 Compare August 12, 2026 11:33
@patchstackdave
patchstackdave merged commit de1e96b into main Aug 12, 2026
4 checks passed
@patchstackdave
patchstackdave deleted the feat/cors-reflection-detection branch August 12, 2026 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants