Skip to content

fix(core): fix trusted origin matching logic#91

Merged
halvaradop merged 6 commits intomasterfrom
fix/origin-matching
Feb 15, 2026
Merged

fix(core): fix trusted origin matching logic#91
halvaradop merged 6 commits intomasterfrom
fix/origin-matching

Conversation

@halvaradop
Copy link
Member

@halvaradop halvaradop commented Feb 15, 2026

Description

This pull request fixes and clarifies the origin matching logic used during signIn and callback flows when requests originate from trusted or untrusted environments. The update improves validation behavior when using the trustedProxyHeaders and trustedOrigins configuration options.

The origin verification process now behaves consistently across the following scenarios:

Origin Matching Behavior

  • When trustedProxyHeaders is NOT configured
    The request origin is derived directly from request.url. Redirects are restricted to the origin where the server is mounted.

  • When trustedOrigins is NOT configured
    Redirects outside the server’s origin are rejected. Only relative paths or absolute URLs matching the request origin are allowed.

  • When BOTH trustedProxyHeaders and trustedOrigins are configured
    This mode supports deployments behind reverse proxies, gateways, or load balancers.
    The incoming request URL is reconstructed using trusted proxy headers and then validated against the trustedOrigins allowlist.

    If the reconstructed origin:

    • is trusted → request proceeds normally
    • is invalid → request is rejected
    • is untrusted but syntactically valid → fallback redirect (/) is returned

Note

A reconstructed URL must match a value defined in trustedOrigins. Otherwise, the request is rejected or redirected to the default path.

Additional Changes

  • Added new tests covering proxy scenarios, malformed origins, and redirect edge cases.
  • Improved handling of Origin, Referer, and redirectTo validation paths.

Resources

@vercel
Copy link

vercel bot commented Feb 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
auth-nextjs-demo Ready Ready Preview, Comment Feb 15, 2026 10:24pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
auth Skipped Skipped Feb 15, 2026 10:24pm

@coderabbitai
Copy link

coderabbitai bot commented Feb 15, 2026

📝 Walkthrough

Walkthrough

Adds origin-trust validation across sign-in and callback flows: new UNTRUSTED_ORIGIN error, context-aware origin resolution honoring proxy headers, stricter origin/pattern validation, and updated redirect logic with enhanced logging and tests.

Changes

Cohort / File(s) Summary
Types & Logging
packages/core/src/@types/index.ts, packages/core/src/logger.ts
Added UNTRUSTED_ORIGIN to AuthInternalErrorCode and a corresponding UNTRUSTED_ORIGIN log message (facility 10, severity error).
Sign-in Authorization
packages/core/src/actions/signIn/authorization.ts
Added getTrustedOrigins; made getOriginURL, createRedirectURI, and createRedirectTo context-aware/async; implemented trusted-origins pattern matching, proxy-header handling, and tightened open-redirect defenses with logging.
Callback Redirect Handling
packages/core/src/actions/callback/callback.ts
Switched redirect validation to use getOriginURL, isSameOrigin/trusted-origin checks; moved context extraction and enriched logs with has_trusted_origins and request_origin.
Pattern Validation
packages/core/src/assert.ts
Added 2048-char guard in patternToRegex and tightened host-pattern regex to limit characters and label lengths (per-label 253 limit).
Tests
packages/core/test/actions/signIn/authorization.test.ts, packages/core/test/actions/signIn/signIn.test.ts, packages/core/test/assert.test.ts
Expanded tests for origin/trustedOrigins, proxy headers, referer handling, wildcard patterns, open-redirect scenarios, and added cases for invalid wildcard patterns.
Docs
docs/src/content/docs/configuration/options.mdx
Expanded and clarified trustedOrigins wildcard and port examples, added warning callout and detailed examples.

Sequence Diagram

sequenceDiagram
    participant Request as Request Handler
    participant AuthFlow as Auth Flow
    participant OriginResolver as Origin Resolver (getOriginURL/getTrustedOrigins)
    participant Validator as Validator (isTrustedOrigin/isSameOrigin)
    participant Logger as Logger

    Request->>AuthFlow: incoming request + redirectTo
    AuthFlow->>OriginResolver: resolve origin (request + context)
    OriginResolver->>OriginResolver: consider proxy headers / derive origin
    OriginResolver->>Validator: check origin against trustedOrigins/patterns
    alt origin trusted
        Validator-->>AuthFlow: valid origin
        AuthFlow->>Logger: log success / store redirect cookie
        AuthFlow-->>Request: proceed with redirect
    else origin untrusted
        Validator-->>Logger: log UNTRUSTED_ORIGIN / OPEN_REDIRECT_ATTACK
        Logger-->>AuthFlow: logged
        AuthFlow-->>Request: reject or fallback to "/"
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

security

Poem

🐰 Soft paws tap the code tonight,

Origins checked, redirects right.
Wildcards trimmed and proxies known,
Cookies kept where trust is sown.
Hop, hop—secure paths home we go!

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(core): fix trusted origin matching logic' directly and specifically describes the primary change: improvements to origin matching logic for the trustedProxyHeaders and trustedOrigins configuration options during signIn and callback flows.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into master

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/origin-matching

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/core/src/actions/callback/callback.ts`:
- Around line 90-106: In the callback handling code in
packages/core/src/actions/callback/callback.ts (inside the redirect validation
block), there's a ReferenceError: the conditional uses undefined variable
`origin.length`; change that to check `origins.length` (the array returned by
getTrustedOrigins) so the isValid calculation uses origins correctly in the
isTrustedOrigin call and subsequent logging/throw path; update the conditional
expression where `origin.length > 0 ? isTrustedOrigin(cookieRedirectTo, origins)
: isSameOrigin(cookieRedirectTo, requestOrigin)` to use `origins.length`
instead.

In `@packages/core/src/actions/signIn/authorization.ts`:
- Around line 56-75: The host header lookup in getOriginURL is inconsistent with
the protocol extraction when context?.trustedProxyHeaders is true: change the
host resolution order to match the protocol's RFC-7239-first approach by
preferring headers.get("Forwarded")?.match(/host=([^;]+)/i)?.[1] then
headers.get("X-Forwarded-Host") then fall back to headers.get("Host"); update
the host assignment used to build origin and keep the rest of the logic
(trustedOrigins via getTrustedOrigins and origin validation via isTrustedOrigin)
unchanged so origin construction and logging still occur when untrusted.

@halvaradop halvaradop added refactor Refactor without changing behavior security Security-related changes, vulnerability fixes, or hardening measures. labels Feb 15, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/core/src/actions/callback/callback.ts (1)

88-108: Redirect validation logic is sound; consider using const.

The fix correctly uses origins.length and implements appropriate validation: trusted-origin check when configured, same-origin fallback otherwise. The enhanced logging with has_trusted_origins and request_origin provides good diagnostic context.

Minor style nit: isValid is never reassigned, so it could be declared with const instead of let.

♻️ Optional: use const for isValid
             if (!isRelativeURL(cookieRedirectTo)) {
-                let isValid =
+                const isValid =
                     origins.length > 0
                         ? isTrustedOrigin(cookieRedirectTo, origins)
                         : isSameOrigin(cookieRedirectTo, requestOrigin)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Refactor without changing behavior security Security-related changes, vulnerability fixes, or hardening measures.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant