tor-browser

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

commit 2e3183bf6fda1b1528e2b54923650e3e73be76bf
parent 4c91d0f47605d299b6faa6ad657121a60e8812e4
Author: Daniel Rubery <drubery@chromium.org>
Date:   Wed,  7 Jan 2026 09:47:53 +0000

Bug 2008047 [wpt PR 56947] - Add WPT for no challenge in the Secure-Session-Registration header, a=testonly

Automatic update from web-platform-tests
Add WPT for no challenge in the Secure-Session-Registration header

This CL adds a WPT validating this works.

Bug: 469801418
Change-Id: Iab681dc69b039aa948ad45b307c60b8a6a6a6964
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7282522
Reviewed-by: Natalie Chanfreau <thefrog@chromium.org>
Commit-Queue: Daniel Rubery <drubery@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1565062}

--

wpt-commits: 52a614a57006f9f4b932fa2f4b5a2ca67af1746b
wpt-pr: 56947

Diffstat:
Mtesting/web-platform/tests/device-bound-session-credentials/login.py | 4+++-
Mtesting/web-platform/tests/device-bound-session-credentials/refresh_session.py | 10+++++-----
Atesting/web-platform/tests/device-bound-session-credentials/registration-no-challenge.https.html | 33+++++++++++++++++++++++++++++++++
Mtesting/web-platform/tests/device-bound-session-credentials/request_early_challenge.py | 2+-
Mtesting/web-platform/tests/device-bound-session-credentials/session_manager.py | 8++++++++
Mtesting/web-platform/tests/device-bound-session-credentials/start_session.py | 21+++++++++++----------
6 files changed, 61 insertions(+), 17 deletions(-)

diff --git a/testing/web-platform/tests/device-bound-session-credentials/login.py b/testing/web-platform/tests/device-bound-session-credentials/login.py @@ -21,7 +21,9 @@ def main(request, response): test_session_manager = session_manager.find_for_request(request) - header_items = ["(RS256)",'challenge="login_challenge_value"',f'path="{registration_url}"'] + header_items = ["(RS256)",f'path="{registration_url}"'] + if test_session_manager.get_allows_challenges(): + header_items.append('challenge="login_challenge_value"') authorization_value = test_session_manager.get_authorization_value() if authorization_value is not None: header_items.append(f'authorization="{authorization_value}"') diff --git a/testing/web-platform/tests/device-bound-session-credentials/refresh_session.py b/testing/web-platform/tests/device-bound-session-credentials/refresh_session.py @@ -27,15 +27,15 @@ def main(request, response): if test_session_manager.get_has_custom_query_param() and 'refreshQueryParam' not in parse_qs(request.url_parts.query): return (400, response.headers, "") - session_key = test_session_manager.get_session_key(session_id) - if session_key == None: - return (400, response.headers, "") - - if test_session_manager.get_refresh_sends_challenge(): + if test_session_manager.get_allows_challenges() and test_session_manager.get_refresh_sends_challenge(): challenge = "refresh_challenge_value" if request.headers.get("Secure-Session-Response") == None: return (403, [('Secure-Session-Challenge', f'"{challenge}";id="{session_id}"')], "") + session_key = test_session_manager.get_session_key(session_id) + if session_key == None: + return (400, response.headers, "") + jwt_header, jwt_payload, verified = jwt_helper.decode_jwt(request.headers.get("Secure-Session-Response").decode('utf-8'), session_key) early_challenge = test_session_manager.get_early_challenge(session_id) diff --git a/testing/web-platform/tests/device-bound-session-credentials/registration-no-challenge.https.html b/testing/web-platform/tests/device-bound-session-credentials/registration-no-challenge.https.html @@ -0,0 +1,33 @@ +<!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 never send back a challenge. + await configureServer({ + allowsChallenges: false + }); + + // Prompt starting a session, and wait until registration completes. + const loginResponse = await fetch('login.py'); + assert_equals(loginResponse.status, 200); + await waitForCookie(expectedCookieAndValue, /*expectCookie=*/true); + + // Confirm that expiring the cookie does refresh because registration succeeded. + expireCookie(expectedCookieAndAttributes); + assert_false(documentHasCookie(expectedCookieAndValue)); + const authResponseAfterExpiry = await fetch('verify_authenticated.py'); + assert_equals(authResponseAfterExpiry.status, 200); + assert_true(documentHasCookie(expectedCookieAndValue)); + }, "Registration header doesn't need a challenge"); +</script> diff --git a/testing/web-platform/tests/device-bound-session-credentials/request_early_challenge.py b/testing/web-platform/tests/device-bound-session-credentials/request_early_challenge.py @@ -22,7 +22,7 @@ def main(request, response): challenges = [] for session_id in session_manager.find_for_request(request).get_session_ids(): early_challenge = test_session_manager.get_early_challenge(session_id) - if early_challenge is not None: + if test_session_manager.get_allows_challenges() and early_challenge is not None: challenges.append(("Secure-Session-Challenge", f'"{early_challenge}";id="{session_id}"')) if use_single_header: 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 @@ -54,6 +54,7 @@ class SessionManager: self.use_empty_response = False self.registration_extra_cookies = [] self.has_custom_query_param = False + self.allows_challenges = True def next_session_id(self): return len(self.session_to_key_map) @@ -169,6 +170,10 @@ class SessionManager: if has_custom_query_param is not None: self.has_custom_query_param = has_custom_query_param + allows_challenges = configuration.get("allowsChallenges") + if allows_challenges is not None: + self.allows_challenges = allows_challenges + def get_should_refresh_end_session(self): return self.should_refresh_end_session @@ -276,3 +281,6 @@ class SessionManager: def get_provider_key(self): return self.provider_key + + def get_allows_challenges(self): + return self.allows_challenges 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 @@ -6,29 +6,30 @@ 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_before_instructions(): + if test_session_manager.get_allows_challenges() and test_session_manager.get_registration_sends_challenge_before_instructions(): # Only send back a challenge on the first call. test_session_manager.reset_registration_sends_challenge_before_instructions() 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 test_session_manager.get_allows_challenges(): + jwt_header, jwt_payload, verified = jwt_helper.decode_jwt(request.headers.get("Secure-Session-Response").decode('utf-8')) + 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, list(response.headers) + extra_cookie_headers, "") + if not verified or jwt_payload.get("jti") != "login_challenge_value": + return (400, list(response.headers) + extra_cookie_headers, "") - if jwt_payload.get("authorization") != test_session_manager.get_authorization_value(): - return (400, list(response.headers) + extra_cookie_headers, "") + if jwt_payload.get("authorization") != test_session_manager.get_authorization_value(): + return (400, list(response.headers) + extra_cookie_headers, "") - if jwt_payload.get("sub") is not None: - return (400, list(response.headers) + extra_cookie_headers, "") + if jwt_payload.get("sub") is not None: + return (400, list(response.headers) + extra_cookie_headers, "") if test_session_manager.get_has_custom_query_param() and 'registrationQueryParam' not in parse_qs(request.url_parts.query): return (400, list(response.headers) + extra_cookie_headers, "") (code, headers, body) = test_session_manager.get_session_instructions_response(session_id, request) headers += extra_cookie_headers - if test_session_manager.get_registration_sends_challenge_with_instructions(): + if test_session_manager.get_allows_challenges() and test_session_manager.get_registration_sends_challenge_with_instructions(): headers.append(('Secure-Session-Challenge', f'"login_challenge_value";id="{session_id}"')) return (code, headers, body)