fix(cors): warn on credentials with null origin#1464
Conversation
`origin: "null"` combined with `credentials: true` is dangerous: sandboxed iframes, `data:`/`file:` documents, and other opaque origins all send `Origin: null`, so credentials would be shared across untrusted contexts. Emit a warn-once message (mirroring the existing wildcard warnings) and document the hazard on the `origin` JSDoc. Co-Authored-By: Claude Fable 5 <[email protected]>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
pi0x
left a comment
There was a problem hiding this comment.
Independent review (did not author this change). Tests pass (test/unit/cors.test.ts, 44 passed) and pnpm lint is clean.
LGTM — well-scoped DX warning with no behavior change to actual CORS resolution:
- Trigger
resolved.credentials && resolved.origin === "null"is correct and properly gated. - Reuses the existing
warnOncehelper, so dedup semantics match the wildcard warnings; the distinct message string dedupes independently. - Test is well-isolated:
exposeHeaders: ["X-Custom"]+ non-wildcard origin ensures exactly one warning fires, sotoHaveBeenCalledOnce()is meaningful. - JSDoc is accurate — sandboxed iframes and
data:/file:/opaque origins do serializeOrigin: null.
Non-blocking suggestion: the warning only fires for the top-level string origin: "null", not for an array containing it (e.g. origin: ["null"]). Unlike the wildcard case — where ["*"] is inert because no real request sends Origin: * — an array containing "null" is a live hazard: isCorsOriginAllowed does origin === _origin over the array, so Origin: null matches and gets reflected with credentials. Consider also covering Array.isArray(resolved.origin) && resolved.origin.includes("null"). Fine to defer since it matches the current wildcard-warning pattern and is warn-only.
🤖 Generated with Claude Code
The array path in `isCorsOriginAllowed` does an exact string comparison, so `origin: ["null"]` matches `Origin: null` requests and is just as hazardous with credentials as the top-level `origin: "null"` string. Co-Authored-By: Claude Fable 5 <[email protected]>
|
Addressed the review gap in e66906d: the warning now also fires when the |
📝 WalkthroughWalkthroughChangesCredentialed null-origin CORS handling
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/unit/cors.test.ts`:
- Around line 97-109: Reset the module-level warnOnce state between the
direct-origin and array-origin tests so each case independently observes its
expected warning. Update the test setup around resolveCorsOptions and warnSpy,
or isolate the module per case, while preserving the global warn-once behavior
in production.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 18a6666f-9cd9-4293-8bc5-9ae6d4293cf7
📒 Files selected for processing (3)
src/utils/cors.tssrc/utils/internal/cors.tstest/unit/cors.test.ts
| it('warns when credentials is used with an origin array containing `"null"`', () => { | ||
| const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); | ||
|
|
||
| // `"null"` in an array is a live hazard too: the array path does an | ||
| // exact string comparison, so an `Origin: null` request matches and | ||
| // is reflected with credentials. | ||
| resolveCorsOptions({ | ||
| credentials: true, | ||
| origin: ["https://example.com", "null"], | ||
| exposeHeaders: ["X-Custom"], | ||
| }); | ||
| expect(warnSpy).toHaveBeenCalledOnce(); | ||
| expect(warnSpy.mock.calls[0][0]).toContain("null"); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Reset warning state between these test cases.
warnOnce keeps a module-level set keyed by the warning text, so the preceding direct-origin test already consumes this exact warning. When this array-origin test runs second, warnSpy receives zero calls and toHaveBeenCalledOnce() fails. Isolate the module state between cases or restructure the tests without changing the intended global warn-once behavior.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/unit/cors.test.ts` around lines 97 - 109, Reset the module-level
warnOnce state between the direct-origin and array-origin tests so each case
independently observes its expected warning. Update the test setup around
resolveCorsOptions and warnSpy, or isolate the module per case, while preserving
the global warn-once behavior in production.
origin: "null"combined withcredentials: trueis dangerous: sandboxed iframes,data:/file:documents, and other opaque origins all sendOrigin: null, so credentials would be shared across untrusted contexts. This adds a warn-once message inresolveCorsOptions, mirroring the existing wildcard-origin and wildcard-exposeHeaderswarnings. The hazard is also documented on theoriginoption JSDoc, and a unit test asserts the warning fires.🤖 Generated with Claude Code
Summary by CodeRabbit
Documentation
origin: "null".Bug Fixes
"null"origins.Tests
"null"origin configurations.