[CFX-7754] Reject browser-forged API keys during dr auth login - #820
Open
chasdr wants to merge 2 commits into
Open
[CFX-7754] Reject browser-forged API keys during dr auth login#820chasdr wants to merge 2 commits into
chasdr wants to merge 2 commits into
Conversation
Why: The `dr auth login` callback listener on localhost:51164 accepted any request for its 5-minute window. A cross-origin `<img src=".../?key=...">` on any open page could plant an attacker's API key, which the CLI then stored as the user's credential. A stray keyless request (favicon probe) was also misread as the CLI-to-CLI port-handover sentinel and aborted the login. Changes: - handleCallback refuses when Sec-Fetch-Dest is present and not "document". The real callback is a top-level navigation; a page cannot forge Sec-Fetch-* headers, so an img/fetch is turned away. Absent stays accepted, which keeps the port handover (a Go client sends no such header) working. - Success page is written only when a key is present; the keyless sentinel gets a 204, which the handover's Go client never reads. - Tests for image/empty refused, document accepted, headerless accepted, keyless image no longer interrupts, keyless headerless still does. Partial by design: does not stop a top-level navigation a hostile page forces (a real document request, but visible), or browsers without fetch metadata. The complete fix is a callback nonce and needs a paired web app change, tracked separately.
|
🎫 Jira: |
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
During
dr auth loginthe CLI runs a local listener onlocalhost:51164for 5 minutes, waiting for the browser to hand back your API key. It accepted any request on that port, so a web page you had open could plant an attacker's key with<img src="http://localhost:51164/?key=ATTACKER_KEY">and the CLI would store it as your credential, so every laterdrcommand ran against the attacker's account. The callback now refuses the forgeable browser requests.Notes for review
The gate is
Sec-Fetch-Destpresent and notdocument. Absent must stay accepted: the CLI-to-CLI port handover uses a Go http client that sends no fetch metadata, and rejecting absent would deadlock two concurrent logins. It does not gate onSec-Fetch-Site, since the real callback is legitimately cross-site.Partial by design. It does not stop a page that forces a full-page navigation (a real
documentrequest, visible in the tab) or browsers older than Safari 16.4. The complete fix is a callback nonce, tracked separately since it needs a web app change.Blocking manual gate, a real login must still work on:
Output
Technical Changes
browserflow.go: refuse whenSec-Fetch-Destis present and notdocument; success page only for a keyed request, 204 for the keyless handover sentinel.browserflow_test.go: image/empty refused, document accepted, headerless accepted, keyless image no longer interrupts, keyless headerless still hands over.Breakdown
Note
High Risk
Touches the login callback that accepts and stores API keys. The gate is partial by design (no
state/nonce), so mistakes here can still accept attacker credentials or break concurrent logins.Overview
Hardens
dr auth loginso a page cannot plant an API key via a forgeable request (<img>/fetch) to the localhost callback while login is in flight.handleCallbacknow returns 403 whenSec-Fetch-Destis present and notdocument. An absent header is still accepted so CLI-to-CLI port handover (Gohttp.Client, no fetch metadata) does not deadlock. Keyless handover gets 204 instead of the success HTML; a keyless browser probe (e.g. favicon) is refused and no longer aborts login.This is a partial mitigation: full-page navigation and clients that can set headers are still in scope. Docs and tests cover the gate, genuine
documentcallbacks, and the handover sentinel.Reviewed by Cursor Bugbot for commit 385eb4a. Configure here.