security(packages/core): harden auth middleware against insecure transport and injection#38
Merged
zrosenbauer merged 6 commits intomainfrom Mar 10, 2026
Merged
Conversation
…sport and injection Enforce HTTPS on OAuth endpoint URLs per RFC 8252 §8.3, with a loopback exemption for local redirect flows. Escape cmd.exe metacharacters in URLs on Windows to prevent command injection. Remove redundant existsSync check in loadFromPath to eliminate a TOCTOU race condition. Co-Authored-By: Claude <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds OAuth endpoint security checks (require HTTPS except for loopback HTTP), escapes cmd.exe metacharacters in URLs on Windows, and removes a pre-check to avoid a TOCTOU race when loading files. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant OAuthStrategy
participant OAuthServer
participant OS
Client->>OAuthStrategy: start OAuth/device-code flow (authUrl, tokenUrl)
OAuthStrategy->>OAuthServer: call isSecureAuthUrl(authUrl)
OAuthServer-->>OAuthStrategy: true/false (HTTPS or loopback HTTP)
OAuthStrategy->>OAuthServer: call isSecureAuthUrl(tokenUrl)
OAuthServer-->>OAuthStrategy: true/false
alt any URL not secure
OAuthStrategy-->>Client: return null (abort flow)
else all URLs secure
OAuthStrategy->>OAuthServer: generate PKCE / device code
OAuthStrategy->>OS: openBrowser(url)
OS->>OAuthServer: on Windows, URL was escaped via escapeCmdMeta
OAuthServer-->>OS: spawn browser command
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
Group URL validation exports together for better readability. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/core/src/middleware/auth/oauth-server.ts`:
- Line 210: The escapeCmdMeta function used in the win32 branch (called from
.with('win32', () => ({ args: ['/c', 'start', '', escapeCmdMeta(url)], command:
'cmd' }))) is incomplete: extend it to also neutralize '%' and both '(' and ')'
characters (either by prefixing each with '^' like the other metacharacters or
by returning a properly quoted URL that prevents cmd.exe variable
expansion/grouping) while preserving existing escaping for &|<>^; update
escapeCmdMeta to consistently escape '%' and parentheses or wrap the final URL
in safe quotes so start receives a literal URL.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c1ef2360-1b7c-4a5a-95be-93e653058ab7
📒 Files selected for processing (1)
packages/core/src/middleware/auth/oauth-server.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
authUrl,tokenUrl,deviceAuthUrl) per RFC 8252 §8.3, allowing HTTP only for loopback addresses (127.0.0.1,[::1],localhost) used during local redirect flowscmd.exemetacharacters in URLs passed tocmd /c starton Windows to prevent command injection via query stringsexistsSynccheck inloadFromPathto eliminate a TOCTOU race conditionChanges
oauth-server.ts: Add exportedisSecureAuthUrl()with privateisLoopbackHost()helper; add privateescapeCmdMeta()helper and apply it to thewin32branch inopenBrowser()strategies/oauth.ts: ValidateauthUrlandtokenUrlwithisSecureAuthUrl()at the top ofresolveFromOAuth(); returnnullfor insecure URLsstrategies/device-code.ts: ValidatedeviceAuthUrlandtokenUrlwithisSecureAuthUrl()at the top ofresolveFromDeviceCode(); returnnullfor insecure URLscreate-store.ts: RemoveexistsSyncguard inloadFromPath(), relying onattempt()to catch read errorsisSecureAuthUrl(7), HTTP rejection inresolveFromOAuth(2) andresolveFromDeviceCode(2), and Windows metacharacter escaping inopenBrowser(1)Testing
pnpm typecheck— no type errorspnpm test— all 456 tests pass (34 test files)pnpm lint— 0 errors (no new warnings introduced)Summary by CodeRabbit
Bug Fixes
Tests
Documentation