Don't forward credentials when the verification fetch encounters a cross-origin redirect - #213
Open
jeremy wants to merge 1 commit into
Conversation
The native redirect-verification fetch attached the WebView's cookies as a static Cookie header and issued the request with a redirect-following client. On a cross-origin redirect, OkHttp forwards that caller-set Cookie header to the destination (it drops Authorization on a host change, but not a caller-set Cookie), delivering first-party cookies to a different origin. The fetch only needs to detect a cross-origin redirect, not follow it with credentials. Disable redirect following on the verification client and resolve the destination from the Location header, comparing the full origin (scheme, host, and port) so a scheme downgrade or port change counts as cross-origin. No credential-bearing request is ever sent to a redirect destination. Session.visitRequestFailedWithNonHttpStatusCode no longer gates on response.isSuccessful (which only held when redirects were followed to a 2xx); detecting the cross-origin redirect response is sufficient to propose the cross-origin redirect visit. Adds HttpRepositoryTest (MockWebServer) covering the no-leak invariant, cross/same-origin detection, and relative Location resolution.
jeremy
force-pushed
the
security/verification-fetch-no-credential-redirect
branch
from
August 28, 2026 07:10
f7f5403 to
fcd94e8
Compare
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
The native redirect-verification fetch in
HttpRepositoryattaches the WebView's cookies to the request as a staticCookieheader and then issues it with a client that follows redirects. When the requested URL responds with a cross-origin redirect, OkHttp forwards that manually-setCookieheader to the redirect destination — delivering first-party session cookies to a different origin. (OkHttp drops theAuthorizationheader when a redirect changes host, but it does not drop a caller-setCookieheader.)This fetch only needs to detect whether the response is a cross-origin redirect; it never needs to follow that redirect with credentials. This change stops following redirects on the verification fetch and inspects the
Locationheader directly, so no credential-bearing request is ever sent to a redirect destination.Changes
followRedirects(false)/followSslRedirects(false).Location. The redirect target is computed by resolving theLocationheader against the request URL, so relative, protocol-relative, and absolute locations are all handled correctly.Session.visitRequestFailedWithNonHttpStatusCodepreviously gated onresponse.isSuccessful, which only held when redirects were followed through to a 2xx. Since the verification fetch no longer follows redirects, the response is the unfollowed 3xx; detecting a cross-origin redirect is now sufficient to propose the cross-origin redirect visit.Only the first redirect hop is inspected — sufficient to detect a direct cross-origin redirect. Deeper same-origin chains that would eventually cross origin now fail closed (the visit fails) rather than being followed with credentials.
Testing
Adds
HttpRepositoryTest(MockWebServer):Cookieor other credential can reach it — while the first-party request still carries its cookies.Locationresolves against the request origin (same-origin).Scope run locally:
./gradlew :core:testDebugUnitTest(core module unit tests).