Repository navigation
🛡️ Sentinel: [HIGH] Fix open-redirect bypass in sign-in return path - #141
Merged
Merged
Conversation
WHATWG URL parsing strips ASCII tab, carriage return and line feed from a URL before using it. A Location header carrying "/\t//evil.example" therefore lands the browser on "//evil.example" once it has been parsed, turning the sign-in return path into an open redirect even though the value began with the single leading "/" the previous check demanded. Reject any of the three characters outright, and extend the test covering the other open-redirect bypasses to pin the new refusal in place. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011MNNzo94dUq2kHjjRCLgAW
jnnngs
marked this pull request as ready for review
November 13, 2026 07:50
Codex Review Summary: ❌ FailedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
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.
🚨 Severity
HIGH. Open redirect on the sign-in flow, which is the most convincing place in the application to have one — a user who has just typed a password is primed to trust whatever page they land on.
💡 Vulnerability
safeReturnPathinauthlogin.gogates the?next=parameter the login page replays after a successful sign-in. It rejects a URL, a protocol-relative//host, and a value containing a backslash, but it does not reject ASCII tab (\t), carriage return (\r) or line feed (\n).The WHATWG URL spec strips those three characters when a browser parses a URL. A value like
"/\t//evil.example"therefore passes the guard — it starts with/, is not//, and contains no\— but once the browser receives aLocation: /\t//evil.exampleheader it parses the string, drops the tab, and navigates to//evil.example, an attacker-controlled host over the same scheme as the sign-in page.🎯 Impact
…/login?next=/%09//evil.examplecan redirect them to an arbitrary host immediately after they sign in. The URL still points at the real console and the landing page can be made to look like the console that was just left.AUTH_MODEsettings that render the sign-in page (local,oidc) are affected.AUTH_MODE=nonedoes not render it, so that default deployment is not in scope.🔧 Fix
One refusal added to the existing guard:
strings.ContainsAny(raw, "\t\r\n"). The docstring records why the three characters specifically, and the existingTestSafeReturnPathtable gains three rows pinning the new refusal in place alongside the other open-redirect bypasses it already covers.Change size: 14 lines across two files.
✅ Verification
go test -run TestSafeReturnPath ./...— passes with the new cases, including a run with the refusal removed from the guard that failed them (so the test was seen to fail).go test -short -count=1 ./...— full short suite green (cmdpackage,connect3270, everyinternal/*).go vet ./...— clean.gofmt -l authlogin.go auth_test.go— clean.The compat suite is skipped under
-shortas expected; this change does not touch the emulator path.Generated by Claude Code