1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
<!DOCTYPE html>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="helper.js" type="module"></script>
<script type="module">
import {
expireCookie,
documentHasCookie,
waitForCookie,
addCookieAndSessionCleanup,
setupShardedServerState,
configureServer,
crossSiteFetch
} from "./helper.js";
promise_test(async t => {
await setupShardedServerState({crossSite: true});
const expectedCookieAndValue = "auth_cookie=abcdef0123";
const expectedCookieAttributes = `Domain=${location.hostname};Path=/device-bound-session-credentials;SameSite=Lax`;
const expectedCookieAndAttributes = `${expectedCookieAndValue};${expectedCookieAttributes}`;
addCookieAndSessionCleanup(t);
configureServer({
// Set cookie details in order to specify that we should only bind a SameSite=Lax cookie for this test.
cookieDetails: [
{
nameAndValue: expectedCookieAndValue,
attributes: expectedCookieAttributes,
}
],
// Since registration happens from a third-party context, we need
// a SameSite=None cookie to tell us that registration completed.
registrationExtraCookies: [
{
nameAndValue: "get_session_instructions=done",
attributes: "SameSite=None;Secure",
}
]
});
// Prompt starting a session in a third-party context, and wait until registration completes.
const loginStatus = await crossSiteFetch(get_host_info().HTTPS_NOTSAMESITE_ORIGIN, `${location.protocol}//${location.host}/device-bound-session-credentials/login.py`, {credentials: "include"});
assert_equals(loginStatus, 200);
await waitForCookie("get_session_instructions=done", /*expectCookie=*/true);
// Since all cookies in the session are first-party, registration
// from a third-party context should fail.
expireCookie(expectedCookieAndAttributes);
assert_false(documentHasCookie(expectedCookieAndValue));
const authResponseAfterExpiry = await fetch('verify_authenticated.py');
assert_equals(authResponseAfterExpiry.status, 403);
assert_false(documentHasCookie(expectedCookieAndValue));
}, "Registration of first-party session not allowed in third-party context");
promise_test(async t => {
await setupShardedServerState({crossSite: true});
const expectedCookieAndValueSameSiteLax = "auth_cookie_lax=abcdef0123";
const expectedCookieAttributesSameSiteLax = `Domain=${location.hostname};Path=/device-bound-session-credentials;SameSite=Lax`;
const expectedCookieAndAttributesSameSiteLax = `${expectedCookieAndValueSameSiteLax};${expectedCookieAttributesSameSiteLax}`;
const expectedCookieAndValueSameSiteNone = "auth_cookie=abcdef0123";
const expectedCookieAttributesSameSiteNone = `Domain=${location.hostname};Path=/device-bound-session-credentials;SameSite=None;Secure`;
const expectedCookieAndAttributesSameSiteNone = `${expectedCookieAndValueSameSiteNone};${expectedCookieAttributesSameSiteNone}`;
addCookieAndSessionCleanup(t);
configureServer({
// Configure the server to bind both a SameSite=Lax and SameSite=None cookie
cookieDetails: [
{
nameAndValue: expectedCookieAndValueSameSiteLax,
attributes: expectedCookieAttributesSameSiteLax,
},
{
nameAndValue: expectedCookieAndValueSameSiteNone,
attributes: expectedCookieAttributesSameSiteNone,
}
],
// Since registration happens from a third-party context, we need
// a SameSite=None cookie to tell us that registration completed.
registrationExtraCookies: [
{
nameAndValue: "get_session_instructions=done",
attributes: "SameSite=None;Secure",
}
]
});
// Prompt starting a session in a third-party context, and wait until registration completes.
const loginStatus = await crossSiteFetch(get_host_info().HTTPS_NOTSAMESITE_ORIGIN, `${location.protocol}//${location.host}/device-bound-session-credentials/login.py`, {credentials: "include"});
assert_equals(loginStatus, 200);
await waitForCookie("get_session_instructions=done", /*expectCookie=*/true);
// Because registration is happenin from a third-party context, only the
// SameSite=None cookie will be set.
assert_false(documentHasCookie(expectedCookieAndValueSameSiteLax));
assert_true(documentHasCookie(expectedCookieAndValueSameSiteNone));
// Since one cookies in the session is third-party, registration
// from a third-party context should succeed.
expireCookie(expectedCookieAndAttributesSameSiteLax);
expireCookie(expectedCookieAndAttributesSameSiteNone);
assert_false(documentHasCookie(expectedCookieAndValueSameSiteLax));
assert_false(documentHasCookie(expectedCookieAndValueSameSiteNone));
const authResponseAfterExpiry = await fetch('verify_authenticated.py');
assert_equals(authResponseAfterExpiry.status, 200);
// While the registration was from a third-party context, the
// refresh triggered by fetching verify_authenticated.py is
// happening in a first-party context. So we get both cookies from
// the refresh.
assert_true(documentHasCookie(expectedCookieAndValueSameSiteLax));
assert_true(documentHasCookie(expectedCookieAndValueSameSiteNone));
}, "Registration of session with third-party cookies allowed in third-party context");
promise_test(async t => {
await setupShardedServerState({crossSite: true});
const expectedCookieAndValue = "auth_cookie=abcdef0123";
const expectedCookieAttributes = `Domain=${location.hostname};Path=/device-bound-session-credentials;SameSite=Lax`;
const expectedCookieAndAttributes = `${expectedCookieAndValue};${expectedCookieAttributes}`;
addCookieAndSessionCleanup(t);
configureServer({
// Set cookie details in order to specify that we should only bind a SameSite=Lax cookie for this test.
cookieDetails: [
{
nameAndValue: expectedCookieAndValue,
attributes: expectedCookieAttributes,
},
],
earlyChallengeForNextRegisteredSession: "early_challenge",
});
// Prompt starting a session in a first-party context, and wait until registration completes.
const loginResponse = await fetch('login.py');
assert_equals(loginResponse.status, 200);
await waitForCookie(expectedCookieAndValue, /*expectCookie=*/true);
// Try to set the challenge from a third-party context
const challengeStatus = await crossSiteFetch(get_host_info().HTTPS_NOTSAMESITE_ORIGIN, `${location.protocol}//${location.host}/device-bound-session-credentials/request_early_challenge.py`, {method: 'POST', body: JSON.stringify({ useSingleHeader: true}), credentials: "include"});
assert_equals(challengeStatus, 200);
// Since all cookies in the session are first-party, our attempt to
// set a challenge from a third-party context should fail. This
// causes a challenge mismatch at registration time.
expireCookie(expectedCookieAndAttributes);
assert_false(documentHasCookie(expectedCookieAndValue));
const authResponseAfterExpiry = await fetch('verify_authenticated.py');
assert_equals(authResponseAfterExpiry.status, 403);
assert_false(documentHasCookie(expectedCookieAndValue));
}, "Set challenge of first-party not allowed in third-party context");
promise_test(async t => {
await setupShardedServerState({crossSite: true});
const expectedCookieAndValueSameSiteLax = "auth_cookie_lax=abcdef0123";
const expectedCookieAttributesSameSiteLax = `Domain=${location.hostname};Path=/device-bound-session-credentials;SameSite=Lax`;
const expectedCookieAndAttributesSameSiteLax = `${expectedCookieAndValueSameSiteLax};${expectedCookieAttributesSameSiteLax}`;
const expectedCookieAndValueSameSiteNone = "auth_cookie=abcdef0123";
const expectedCookieAttributesSameSiteNone = `Domain=${location.hostname};Path=/device-bound-session-credentials;SameSite=None;Secure`;
const expectedCookieAndAttributesSameSiteNone = `${expectedCookieAndValueSameSiteNone};${expectedCookieAttributesSameSiteNone}`;
addCookieAndSessionCleanup(t);
configureServer({
// Configure the server to bind both a SameSite=Lax and SameSite=None cookie
cookieDetails: [
{
nameAndValue: expectedCookieAndValueSameSiteLax,
attributes: expectedCookieAttributesSameSiteLax,
},
{
nameAndValue: expectedCookieAndValueSameSiteNone,
attributes: expectedCookieAttributesSameSiteNone,
}
],
earlyChallengeForNextRegisteredSession: "early_challenge",
});
// Prompt starting a session in a first-party context, and wait until registration completes.
const loginResponse = await fetch('login.py');
assert_equals(loginResponse.status, 200);
await waitForCookie(expectedCookieAndValueSameSiteNone, /*expectCookie=*/true);
// Try to set the challenge from a third-party context
const challengeStatus = await crossSiteFetch(get_host_info().HTTPS_NOTSAMESITE_ORIGIN, `${location.protocol}//${location.host}/device-bound-session-credentials/request_early_challenge.py`, {method: 'POST', body: JSON.stringify({ useSingleHeader: true}), credentials: "include"});
assert_equals(challengeStatus, 200);
// Since one cookie in the session is third-party, our attempt to
// set a challenge from a third-party context should succeed.
expireCookie(expectedCookieAndAttributesSameSiteLax);
expireCookie(expectedCookieAndAttributesSameSiteNone);
assert_false(documentHasCookie(expectedCookieAndValueSameSiteLax));
assert_false(documentHasCookie(expectedCookieAndValueSameSiteNone));
const authResponseAfterExpiry = await fetch('verify_authenticated.py');
assert_equals(authResponseAfterExpiry.status, 200);
// While the challenge was set in a third-party context, the refresh
// triggered by fetching verify_authenticated.py is happening in a
// first-party context. So we get both cookies from the refresh.
assert_true(documentHasCookie(expectedCookieAndValueSameSiteLax));
assert_true(documentHasCookie(expectedCookieAndValueSameSiteNone));
}, "Set challenge of session with third-party cookies allowed in third-party context");
</script>
|