File: third-party-registration.https.html

package info (click to toggle)
firefox 145.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,653,344 kB
  • sloc: cpp: 7,594,932; javascript: 6,459,612; ansic: 3,752,905; python: 1,403,433; xml: 629,811; asm: 438,677; java: 186,421; sh: 67,287; makefile: 19,169; objc: 13,086; perl: 12,982; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10
file content (202 lines) | stat: -rw-r--r-- 10,474 bytes parent folder | download | duplicates (2)
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>