-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Credentialless]: Add tests about the HTTP cache.
The request's includeCredentials isn't part of the HTTP cache key. It means if: - a.com requests c.com with credentials, - b.com requests c.com without credentials Then both a.com and b.com will get a response requested with credentials. This seems problematic in general. The request's credential mode is not respected, and a.com influences directly b.com. The partitioned HTTP cache will solve one of the two problem. With COEP:credentialless, we obviously don't want to request a resource without credentials and get a response with credentials. That would be a security issue. Here is a WPT test about it. Bug: whatwg/fetch#1253 Bug: 1218023 Change-Id: I888dc020a8ae770816d0fbc42e8803df3ba66392 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2961290 Reviewed-by: Mike West <[email protected]> Commit-Queue: Arthur Sonzogni <[email protected]> Cr-Commit-Position: refs/heads/master@{#893398}
- Loading branch information
1 parent
03c5072
commit c42d9bc
Showing
3 changed files
with
118 additions
and
2 deletions.
There are no files selected for viewing
92 changes: 92 additions & 0 deletions
92
html/cross-origin-embedder-policy/credentialless/cache.tentative.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/get-host-info.sub.js"></script> | ||
<script src="/common/utils.js"></script> | ||
<script src="./resources/common.js"></script> | ||
<script src="./resources/dispatcher.js"></script> | ||
<script> | ||
|
||
// With COEP:credentialless, requesting a resource without credentials MUST NOT | ||
// return a response requested with credentials. This would be a security | ||
// issue, since COEP:credentialless can be used to enable crossOriginIsolation. | ||
// | ||
// The test the behavior of the HTTP cache: | ||
// 1. b.com stores cookie. | ||
// 2. a.com(COEP:unsafe-none): request b.com's resource. | ||
// 3. a.com(COEP:credentialless): request b.com's resource. | ||
// | ||
// The first time, the resource is requested with credentials. The response is | ||
// served with Cache-Control: max-age=31536000. It enters the cache. | ||
// The second time, the resource is requested without credentials. The response | ||
// in the cache must not be returned. | ||
|
||
const cookie_key = "coep_cache_key"; | ||
const cookie_value = "coep_cache_value"; | ||
const same_origin = get_host_info().HTTPS_ORIGIN; | ||
const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; | ||
const cacheable_response_path = | ||
"/html/cross-origin-embedder-policy/credentialless/resources/cacheable-response.py"; | ||
|
||
const GetCookie = (response) => { | ||
return parseCookies(JSON.parse(response))[cookie_key]; | ||
} | ||
|
||
// "same_origin" document with COEP:unsafe-none. | ||
const w_coep_none_token = token(); | ||
const w_coep_none_url = same_origin + executor_path + coep_none + | ||
`&uuid=${w_coep_none_token}` | ||
const w_coep_none = window.open(w_coep_none_url); | ||
add_completion_callback(() => w_coep_none.close()); | ||
|
||
// "same_origin" document with COEP:credentialles. | ||
const w_coep_credentialless_token = token(); | ||
const w_coep_credentialless_url = same_origin + executor_path + | ||
coep_credentialless + `&uuid=${w_coep_credentialless_token}` | ||
const w_coep_credentialless = window.open(w_coep_credentialless_url); | ||
add_completion_callback(() => w_coep_credentialless.close()); | ||
|
||
const this_token = token(); | ||
|
||
// A request toward a "cross-origin" cacheable response. | ||
const request_token = token(); | ||
const request_url = cross_origin + cacheable_response_path + | ||
`?uuid=${request_token}`; | ||
|
||
promise_setup(async test => { | ||
await setCookie(cross_origin, cookie_key, cookie_value); | ||
}, "Set cookie"); | ||
|
||
// The "same-origin" COEP:unsafe-none document fetchs a "cross-origin" | ||
// resource. The request is sent with credentials. | ||
promise_setup(async test => { | ||
send(w_coep_none_token, ` | ||
await fetch("${request_url}", { | ||
mode : "no-cors", | ||
credentials: "include", | ||
}); | ||
send("${this_token}", "Resource fetched"); | ||
`); | ||
|
||
assert_equals(await receive(this_token), "Resource fetched"); | ||
assert_equals(await receive(request_token).then(GetCookie), cookie_value); | ||
}, "Cache a response requested with credentials"); | ||
|
||
// The "same-origin" COEP:credentialless document fetches the same resource | ||
// without credentials. The HTTP cache must not be used. Instead a second | ||
// request must be made without credentials. | ||
promise_test(async test => { | ||
send(w_coep_credentialless_token, ` | ||
await fetch("${request_url}", { | ||
mode : "no-cors", | ||
credentials: "include", | ||
}); | ||
send("${this_token}", "Resource fetched"); | ||
`); | ||
|
||
assert_equals(await receive(this_token), "Resource fetched"); | ||
|
||
test.step_timeout(test.unreached_func("The HTTP cache has been used"), 1500); | ||
assert_equals(await receive(request_token).then(GetCookie), undefined); | ||
}, "The HTTP cache must not be used"); | ||
|
||
</script> |
24 changes: 24 additions & 0 deletions
24
html/cross-origin-embedder-policy/credentialless/resources/cacheable-response.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import json | ||
from wptserve.utils import isomorphic_decode | ||
|
||
# A server providing a cacheable response and storing the request's headers | ||
# toward the `uuid` attribute stash. | ||
def main(request, response): | ||
# The response served is cacheable by the navigator: | ||
response.headers.set(b"Cache-Control", b"max-age=31536000"); | ||
|
||
uuid = request.GET[b'uuid']; | ||
headers = {}; | ||
for key, value in request.headers.items(): | ||
headers[isomorphic_decode(key)] = isomorphic_decode(request.headers[key]) | ||
headers = json.dumps(headers); | ||
|
||
# The stash is accessed concurrently by many clients. A lock is used to | ||
# avoid unterleaved read/write from different clients. | ||
stash = request.server.stash; | ||
with stash.lock: | ||
queue = stash.take(uuid, '/coep-credentialless') or []; | ||
queue.append(headers); | ||
stash.put(uuid, queue, '/coep-credentialless'); | ||
return b"done"; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters