tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 6e07bafeca84659e3ed68fc8bbbdaf8c2bf31f27
parent acf9923c943b1d49af7c7288ddd8f8ad80b33981
Author: Daniel Rubery <drubery@chromium.org>
Date:   Thu,  9 Oct 2025 18:06:34 +0000

Bug 1992102 [wpt PR 55134] - Add WPT that registration cannot set challenge, a=testonly

Automatic update from web-platform-tests
Add WPT that registration cannot set challenge

A 403 during registration is always a failure, even if a challenge
header is provided.

Bug: 438783634
Change-Id: Iba688f9dbbf43496c61b1d4ade85ee0ba95ee6df
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6991109
Reviewed-by: thefrog <thefrog@chromium.org>
Commit-Queue: Daniel Rubery <drubery@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1522313}

--

wpt-commits: c517e52a628888bd30ab07b0fe2687a5fb04e055
wpt-pr: 55134

Diffstat:
Atesting/web-platform/tests/device-bound-session-credentials/registration-sends-challenge.https.html | 40++++++++++++++++++++++++++++++++++++++++
Mtesting/web-platform/tests/device-bound-session-credentials/session_manager.py | 6+++---
Mtesting/web-platform/tests/device-bound-session-credentials/start_session.py | 12+++++++-----
3 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/testing/web-platform/tests/device-bound-session-credentials/registration-sends-challenge.https.html b/testing/web-platform/tests/device-bound-session-credentials/registration-sends-challenge.https.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="helper.js" type="module"></script> + +<script type="module"> + import { expireCookie, waitForCookie, addCookieAndSessionCleanup, configureServer, setupShardedServerState, documentHasCookie } from "./helper.js"; + + promise_test(async t => { + await setupShardedServerState(); + const expectedCookieAndValue = "auth_cookie=abcdef0123"; + const expectedCookieAndAttributes = `${expectedCookieAndValue};Domain=${location.hostname};Path=/device-bound-session-credentials`; + addCookieAndSessionCleanup(t); + + // Configure server to send back a challenge during registration. + await configureServer({ + registrationSendsChallenge: true, + // Since registration fails, we use a cookie to tell us that the + // response was received. + registrationExtraCookies: [ + { + nameAndValue: "dbsc_registration=done", + } + ] + }); + + // Prompt starting a session, and wait until registration completes. + const loginResponse = await fetch('login.py'); + assert_equals(loginResponse.status, 200); + await waitForCookie("dbsc_registration=done", /*expectCookie=*/true); + + // Confirm that expiring the cookie does not refresh because registration failed. + expireCookie(expectedCookieAndAttributes); + assert_false(documentHasCookie(expectedCookieAndValue)); + const authResponseAfterExpiry = await fetch('verify_authenticated.py'); + assert_equals(authResponseAfterExpiry.status, 403); + assert_false(documentHasCookie(expectedCookieAndValue)); +}, "Registration can't send back 403 with challenge"); +</script> diff --git a/testing/web-platform/tests/device-bound-session-credentials/session_manager.py b/testing/web-platform/tests/device-bound-session-credentials/session_manager.py @@ -201,10 +201,10 @@ class SessionManager: "attributes": cookie_detail.get_attributes(request) }, self.get_cookie_details(session_id))) - def get_session_instructions_response_set_cookie_headers(self, session_id, request): + def get_set_cookie_headers(self, cookies, request): header_values = list(map( lambda cookie_detail: f"{cookie_detail.get_name_and_value()}; {cookie_detail.get_attributes(request)}", - self.get_cookie_details(session_id) + self.registration_extra_cookies + cookies )) return [("Set-Cookie", header_value) for header_value in header_values] @@ -233,7 +233,7 @@ class SessionManager: "credentials": self.get_sessions_instructions_response_credentials(session_id, request), "allowed_refresh_initiators": self.allowed_refresh_initiators, } - headers = self.get_session_instructions_response_set_cookie_headers(session_id, request) + [ + headers = self.get_set_cookie_headers(self.get_cookie_details(session_id), request) + [ ("Content-Type", "application/json"), ("Cache-Control", "no-store") ] diff --git a/testing/web-platform/tests/device-bound-session-credentials/start_session.py b/testing/web-platform/tests/device-bound-session-credentials/start_session.py @@ -4,22 +4,24 @@ session_manager = importlib.import_module('device-bound-session-credentials.sess def main(request, response): test_session_manager = session_manager.find_for_request(request) + extra_cookie_headers = test_session_manager.get_set_cookie_headers(test_session_manager.registration_extra_cookies, request) if test_session_manager.get_registration_sends_challenge(): # Only send back a challenge on the first call. test_session_manager.reset_registration_sends_challenge() - return (403, [('Secure-Session-Challenge', '"login_challenge_value"')], "") + return (403, [('Secure-Session-Challenge', '"login_challenge_value"')] + extra_cookie_headers, "") jwt_header, jwt_payload, verified = jwt_helper.decode_jwt(request.headers.get("Secure-Session-Response").decode('utf-8')) session_id = test_session_manager.create_new_session() test_session_manager.set_session_key(session_id, jwt_header.get('jwk')) if not verified or jwt_payload.get("jti") != "login_challenge_value": - return (400, response.headers, "") + return (400, response.headers + extra_cookie_headers, "") if jwt_payload.get("authorization") != test_session_manager.get_authorization_value(): - return (400, response.headers, "") + return (400, response.headers + extra_cookie_headers, "") if jwt_payload.get("sub") is not None: - return (400, response.headers, "") + return (400, response.headers + extra_cookie_headers, "") - return test_session_manager.get_session_instructions_response(session_id, request) + (code, headers, body) = test_session_manager.get_session_instructions_response(session_id, request) + return (code, headers + extra_cookie_headers, body)