summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html
blob: ffb419f7995ff46a6fdc6b6846b534fb1cef71ce (plain)
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
<!doctype html>
<meta charset="utf-8">
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/storage-access-api/helpers.js"></script>
<script>
(async function() {
  test_driver.set_test_context(window.top);
  const type = (new URLSearchParams(window.location.search)).get("type");
  const id = (new URLSearchParams(window.location.search)).get("id");
  let message = "HasAccess for " + type;
  // Step 6 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
  try {
    await MaybeSetStorageAccess("*", "*", "blocked");
    await test_driver.set_permission({ name: 'storage-access' }, 'granted');
    switch (type) {
      case "none": {
        let couldRequestStorageAccessForNone = true;
        try {
          await document.requestStorageAccess({});
        } catch (_) {
          couldRequestStorageAccessForNone = false;
        }
        if (couldRequestStorageAccessForNone) {
          message = "Requesting access for {} should fail."
        }
        let couldRequestStorageAccessForAllFalse = true;
        try {
          await document.requestStorageAccess({all:false});
        } catch (_) {
          couldRequestStorageAccessForAllFalse = false;
        }
        if (couldRequestStorageAccessForAllFalse) {
          message = "Requesting access for {all:false} should fail."
        }
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        break;
      }
      case "cookies": {
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess || document.cookie.includes("test="+id)) {
          message = "First-party cookies should not be readable before handle is loaded.";
        }
        await document.requestStorageAccess({cookies: true});
        hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (!hasUnpartitionedCookieAccess || !document.cookie.includes("test="+id)) {
          message = "First-party cookies should be readable if cookies were requested.";
        }
        break;
      }
      case "sessionStorage": {
        const handle = await document.requestStorageAccess({sessionStorage: true});
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        if (id != handle.sessionStorage.getItem("test")) {
          message = "No first-party Session Storage access";
        }
        if (!!window.sessionStorage.getItem("test")) {
          message = "Handle should not override window Session Storage";
        }
        window.onstorage = (e) => {
          if (e.key == "window_event") {
            if (e.newValue != id) {
              handle.sessionStorage.setItem("handle_event", "wrong data " + e.newValue);
            } else if (e.storageArea != handle.sessionStorage) {
              handle.sessionStorage.setItem("handle_event", "storage area mismatch");
            } else {
              handle.sessionStorage.setItem("handle_event", id);
            }
          }
        };
        break;
      }
      case "localStorage": {
        const handle = await document.requestStorageAccess({localStorage: true});
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        if (id != handle.localStorage.getItem("test")) {
          message = "No first-party Local Storage access";
        }
        if (!!window.localStorage.getItem("test")) {
          message = "Handle should not override window Local Storage";
        }
        window.onstorage = (e) => {
          if (e.key == "window_event") {
            if (e.newValue != id) {
              handle.localStorage.setItem("handle_event", "wrong data " + e.newValue);
            } else if (e.storageArea != handle.localStorage) {
              handle.localStorage.setItem("handle_event", "storage area mismatch");
            } else {
              handle.localStorage.setItem("handle_event", id);
            }
          }
        };
        break;
      }
      case "indexedDB": {
        const handle = await document.requestStorageAccess({indexedDB: true});
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        const handle_dbs = await handle.indexedDB.databases();
        if (handle_dbs.length != 1 || handle_dbs[0].name != id) {
          message = "No first-party IndexedDB access";
        }
        const local_dbs = await window.indexedDB.databases();
        if (local_dbs.length != 0) {
          message = "Handle should not override window IndexedDB";
        }
        await handle.indexedDB.deleteDatabase(id);
        break;
      }
      case "locks": {
        const handle = await document.requestStorageAccess({locks: true});
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        const handle_state = await handle.locks.query();
        if (handle_state.held.length != 1 || handle_state.held[0].name != id) {
          message = "No first-party Web Lock access";
        }
        const local_state = await window.navigator.locks.query();
        if (local_state.held.length != 0) {
          message = "Handle should not override window Web Locks";
        }
        await handle.locks.request(id, {steal: true}, async () => {});
        break;
      }
      case "caches": {
        const handle = await document.requestStorageAccess({caches: true});
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        const handle_has = await handle.caches.has(id);
        if (!handle_has) {
          message = "No first-party Cache Storage access";
        }
        const local_has = await window.caches.has(id);
        if (local_has) {
          message = "Handle should not override window Cache Storage";
        }
        await handle.caches.delete(id);
        break;
      }
      case "getDirectory": {
        const handle = await document.requestStorageAccess({getDirectory: true});
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        const handle_root = await handle.getDirectory();
        let handle_has = await handle_root.getFileHandle(id).then(() => true, () => false);
        if (!handle_has) {
          message = "No first-party Origin Private File System access";
        }
        const local_root = await window.navigator.storage.getDirectory();
        let local_has = await local_root.getFileHandle(id).then(() => true, () => false);
        if (local_has) {
          message = "Handle should not override window Origin Private File System";
        }
        await handle_root.removeEntry(id);
        break;
      }
      case "estimate": {
        const handle = await document.requestStorageAccess({estimate: true});
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        const handle_estimate = await handle.estimate();
        if (handle_estimate.usage  <= 0) {
          message = "No first-party quota access";
        }
        const local_estimate = await window.navigator.storage.estimate();
        if (local_estimate > 0) {
          message = "Handle should not override window quota";
        }
        break;
      }
      case "blobStorage": {
        const handle = await document.requestStorageAccess({createObjectURL: true, revokeObjectURL: true});
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        let blob = await fetch(atob(id)).then(
          (response) => response.text(),
          () => "");
        if (blob != "TEST") {
          message = "Blob storage should be readable in this context";
        }
        URL.revokeObjectURL(atob(id));
        blob = await fetch(atob(id)).then(
          (response) => response.text(),
          () => "");
        if (blob != "TEST") {
          message = "Handle should not override window blob storage";
        }
        handle.revokeObjectURL(atob(id));
        blob = await fetch(atob(id)).then(
          (response) => response.text(),
          () => "");
        if (blob != "") {
          message = "No first-party blob access";
        }
        const url = handle.createObjectURL(new Blob(["TEST2"]));
        blob = await fetch(url).then(
          (response) => response.text(),
          () => "");
        if (blob != "TEST2") {
          message = "A blob url created via the handle should be readable";
        }
        handle.revokeObjectURL(url);
        blob = await fetch(url).then(
          (response) => response.text(),
          () => "");
        if (blob != "") {
          message = "A blob url removed via the handle should be cleared";
        }
        break;
      }
      case "BroadcastChannel": {
        const handle = await document.requestStorageAccess({BroadcastChannel: true});
        let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
        if (hasUnpartitionedCookieAccess) {
          message = "First-party cookies should not be readable if not requested.";
        }
        const handle_channel = handle.BroadcastChannel(id);
        handle_channel.postMessage("Same-origin handle access");
        handle_channel.close();
        const local_channel = new BroadcastChannel(id);
        local_channel.postMessage("Same-origin local access");
        local_channel.close();
        break;
      }
      default: {
        message = "Unexpected type " + type;
        break;
      }
    }
  } catch (_) {
    message = "Unable to load handle in same-origin context for " + type;
  }
  // Step 7 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
  await MaybeSetStorageAccess("*", "*", "allowed");
  await test_driver.set_permission({ name: 'storage-access' }, 'prompt');
  window.top.postMessage(message, "*");
})();
</script>