Skip to content

Commit d803d63

Browse files
Daniel Ruberychromium-wpt-export-bot
Daniel Rubery
authored andcommitted
Add WPT for cross-site requests with credentials omitted
I initially thought this would trigger refreshes since we don't check credentials mode in Session::ShouldDeferRequest. It turns out there's an implicit dependency since the caller of SessionService::ShouldDefer is UrlRequestHttpJob::SetCookieHeaderAndStart, which is only called when credentials mode allows credentials. It seems worth testing that behavior, since it's an important primitive for mitigating cross-site leaks. Change-Id: Id7738597eaeb966167a4d8d71f69798648d684c2 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6394915 Reviewed-by: thefrog <[email protected]> Commit-Queue: Daniel Rubery <[email protected]> Cr-Commit-Position: refs/heads/main@{#1438968}
1 parent e1fc38c commit d803d63

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>DBSC does not refresh cross-site fetch without credentials</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<script src="/common/get-host-info.sub.js"></script>
7+
<script src="helper.js" type="module"></script>
8+
9+
<script type="module">
10+
import { documentHasCookie, expireCookie, waitForCookie, addCookieAndSessionCleanup, setupShardedServerState, configureServer } from "./helper.js";
11+
12+
promise_test(async t => {
13+
const testId = await setupShardedServerState();
14+
const expectedCookieAndValue = "auth_cookie=abcdef0123";
15+
const expectedCookieAndAttributes = `${expectedCookieAndValue};Domain=${location.hostname};Path=/device-bound-session-credentials`;
16+
addCookieAndSessionCleanup(t);
17+
18+
// Prompt starting a session, and wait until registration completes.
19+
const loginResponse = await fetch('login.py');
20+
assert_equals(loginResponse.status, 200);
21+
await waitForCookie(expectedCookieAndValue, /*expectCookie=*/true);
22+
23+
// Expire the cookies
24+
expireCookie(expectedCookieAndAttributes);
25+
26+
// Setup for receiving messages
27+
let messageCallbacks = [];
28+
function messageListener(event) {
29+
if (messageCallbacks.length > 0) {
30+
messageCallbacks[0](event.data);
31+
messageCallbacks.shift();
32+
}
33+
};
34+
window.addEventListener("message", messageListener);
35+
t.add_cleanup(() => {
36+
window.removeEventListener("message", messageListener);
37+
});
38+
39+
function getMessage() {
40+
return new Promise((resolve, reject) => {
41+
messageCallbacks.push(resolve);
42+
});
43+
}
44+
45+
// Create a cross-site iframe that's going to try to fetch without credentials
46+
let iframe = document.createElement('iframe');
47+
iframe.src = `${get_host_info().HTTPS_NOTSAMESITE_ORIGIN}/device-bound-session-credentials/fetch-verify-authenticated.https.html`;
48+
document.body.appendChild(iframe);
49+
50+
let statusCode = await getMessage();
51+
assert_equals(statusCode, 401);
52+
53+
// We should not have refreshed.
54+
assert_false(documentHasCookie(expectedCookieAndValue));
55+
}, "A cross-site fetch without credentials should not refresh");
56+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<script src="/common/get-host-info.sub.js"></script>
3+
<body>
4+
<script>
5+
async function onload() {
6+
let base_origin = get_host_info().ORIGIN;
7+
let response = await fetch(`${base_origin}/device-bound-session-credentials/verify_authenticated.py`, {credentials: "omit"});
8+
window.parent.postMessage(response.status, base_origin);
9+
}
10+
onload();
11+
</script>
12+
</body>

0 commit comments

Comments
 (0)