Commit ddb23f27 authored by Dominic Farolino's avatar Dominic Farolino Committed by Commit Bot

Change default classic script fetch options credentials mode

This CL changes the default classic script fetch options credentials mode
from "omit" to "same-origin", as per the recent spec change [1], and adds
descendant worker credentials tests as a follow-up to said spec change and
[2].

[1]: https://github.com/whatwg/html/pull/3656
[2]: https://github.com/web-platform-tests/wpt/issues/13426

R=domenic@chromium.org, kouhei@chromium.org, nhiroki@chromium.org

Bug: 849101
Change-Id: I958f552f0ee91beb8aab98269f79a1eb219fb40a
Reviewed-on: https://chromium-review.googlesource.com/c/1301964
Commit-Queue: Dominic Farolino <domfarolino@gmail.com>
Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604862}
parent e0104ef4
......@@ -2,84 +2,302 @@
<title>DedicatedWorker: WorkerOptions 'credentials'</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script>
host_info = get_host_info();
// Determines the expected cookie value to be reported by a dedicated worker
// based on the given option. The worker reports an empty string as the actual
// cookie value if the cookie wasn't sent to the server. Otherwise, it's the
// value set by the headers file:
// "dedicated-worker-options-credentials.html.headers"
function DetermineExpectedCookieValue(options) {
// Classic script loading should always send credentials regardless of the
// 'credentials' option because the spec says the option takes effect only
// for module script loading.
if (options.type == 'classic')
return 'COOKIE_VALUE';
assert_equals(options.type, 'module');
if (!options.credentials ||
options.credentials == 'same-origin' ||
options.credentials == 'include') {
return 'COOKIE_VALUE';
function DetermineExpectedCookieValue(options, config) {
// Valid WorkerOptions and test config checking.
if (config.origin !== 'same' && config.origin !== 'remote')
assert_unreached('Invalid config.origin was specified: ' + config.origin);
if (options.credentials && options.credentials !== 'omit' &&
options.credentials !== 'same-origin' &&
options.credentials !== 'include') {
assert_unreached('Invalid credentials option was specified: ' +
options.credentials);
}
if (options.credentials == 'omit')
if (options.type !== 'classic' && options.type !== 'module')
assert_unreached('Invalid type option was specified: ' + options.type);
if (options.type === 'classic')
return (config.origin === 'same') ? '1' : '';
if (options.credentials === 'omit')
return '';
assert_unreached('Invalid credentials option was specified: ' +
options.credentials);
else if (options.credentials === 'include')
return '1';
else
return (config.origin === 'same') ? '1' : '';
}
// Runs a credentials test with the given WorkerOptions.
function credentials_test(options, description) {
//
// |options| is a WorkerOptions dict.
// |config| has options as follows:
//
// config = {
// fetchType: 'top-level' or 'descendant-static' or 'descendant-dynamic'
// origin: 'remote' or 'same'
// };
//
// - |config.fetchType| indicates the type of script to load for the test.
// - |config.origin| indicates same-origin-ness of the script to load.
function credentials_test(options, config, description) {
promise_test(async () => {
const worker = new Worker('resources/credentials.py', options);
let workerURL, origin = config.origin;
if (config.fetchType === 'top-level') {
workerURL = 'resources/credentials.py';
} else if (config.fetchType === 'descendant-static') {
workerURL =
`resources/static-import-${origin}-origin-credentials-checker-worker.${origin === 'same' ? '' : 'sub.'}js`;
} else if (config.fetchType === 'descendant-dynamic') {
workerURL =
`resources/dynamic-import-${origin}-origin-credentials-checker-worker.${origin === 'same' ? '' : 'sub.'}js`;
} else {
assert_unreached('Invalid config.fetchType: ' + config.fetchType);
}
const worker = new Worker(workerURL, options);
// Wait until the worker sends the actual cookie value.
const msg_event = await new Promise(resolve => worker.onmessage = resolve);
const expectedCookieValue = DetermineExpectedCookieValue(options);
const expectedCookieValue = DetermineExpectedCookieValue(options, config);
assert_equals(msg_event.data, expectedCookieValue);
}, description);
}
// Tests for module scripts.
function init() {
// Same-origin cookie is set up in the .headers file in this directory.
promise_test(async () => {
return fetch(
`${host_info.HTTP_REMOTE_ORIGIN}/cookies/resources/set-cookie.py?name=COOKIE_NAME&path=/workers/modules/`,
{
mode: 'no-cors',
credentials: 'include'
});
}, 'Test initialization: setting up cross-origin cookie');
}
init();
// Tests for module workers.
credentials_test(
{ type: 'module' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and send the credentials');
credentials_test(
{ credentials: 'omit', type: 'module' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=module and credentials=omit should not send the ' +
'credentials');
credentials_test(
{ credentials: 'same-origin', type: 'module' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=module and credentials=same-origin should send ' +
'the credentials');
credentials_test(
{ credentials: 'include', type: 'module' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials');
// Tests for module worker static imports.
credentials_test(
{ type: 'module' },
{ fetchType: 'descendant-static', origin: 'same' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and send the credentials for ' +
'same-origin static imports');
credentials_test(
{ credentials: 'omit', type: 'module' },
{ fetchType: 'descendant-static', origin: 'same' },
'new Worker() with type=module and credentials=omit should not send the ' +
'credentials for same-origin static imports');
credentials_test(
{ credentials: 'same-origin', type: 'module' },
{ fetchType: 'descendant-static', origin: 'same' },
'new Worker() with type=module and credentials=same-origin should send ' +
'the credentials for same-origin static imports');
credentials_test(
{ credentials: 'include', type: 'module' },
{ fetchType: 'descendant-static', origin: 'same' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials for same-origin static imports');
credentials_test(
{ type: 'module' },
{ fetchType: 'descendant-static', origin: 'remote' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and not send the credentials for ' +
'cross-origin static imports');
credentials_test(
{ credentials: 'omit', type: 'module' },
{ fetchType: 'descendant-static', origin: 'remote' },
'new Worker() with type-module credentials=omit should not send the ' +
'credentials for cross-origin static imports');
credentials_test(
{ credentials: 'same-origin', type: 'module' },
{ fetchType: 'descendant-static', origin: 'remote' },
'new Worker() with type=module and credentials=same-origin should not ' +
'send the credentials for cross-origin static imports');
credentials_test(
{ credentials: 'include', type: 'module' },
{ fetchType: 'descendant-static', origin: 'remote' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials for cross-origin static imports');
// Tests for module worker dynamic imports.
credentials_test(
{ type: 'module' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and send the credentials for ' +
'same-origin dynamic imports');
credentials_test(
{ credentials: 'omit', type: 'module' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=module and credentials=omit should not send the ' +
'credentials for same-origin dynamic imports');
credentials_test(
{ credentials: 'same-origin', type: 'module' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=module and credentials=same-origin should send ' +
'the credentials for same-origin dynamic imports');
credentials_test(
{ credentials: 'include', type: 'module' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials for same-origin dynamic imports');
credentials_test(
{ type: 'module'},
'new Worker() with the default credentials option should behave as ' +
'credentials=same-origin and send the credentials');
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=module and default credentials option should ' +
'behave as credentials=same-origin and not send the credentials for ' +
'cross-origin dynamic imports');
credentials_test(
{ credentials: 'omit', type: 'module' },
'new Worker() with credentials=omit should not send the credentials');
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type-module credentials=omit should not send the ' +
'credentials for cross-origin dynamic imports');
credentials_test(
{ credentials: 'same-origin', type: 'module' },
'new Worker() with credentials=same-origin should send the credentials');
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=module and credentials=same-origin should not ' +
'send the credentials for cross-origin dynamic imports');
credentials_test(
{ credentials: 'include', type: 'module' },
'new Worker() with credentials=include should send the credentials');
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=module and credentials=include should send the ' +
'credentials for cross-origin dynamic imports');
// Tests for classic scripts.
// Tests for classic workers.
// TODO(domfarolino): Maybe move classic worker tests up a directory?
credentials_test(
{ type: 'classic' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=classic should always send the credentials ' +
'regardless of the credentials option (default).');
credentials_test(
{ credentials: 'omit', type: 'classic' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=classic should always send the credentials ' +
'regardless of the credentials option (omit).');
credentials_test(
{ credentials: 'same-origin', type: 'classic' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=classic should always send the credentials ' +
'regardless of the credentials option (same-origin).');
credentials_test(
{ credentials: 'include', type: 'classic' },
{ fetchType: 'top-level', origin: 'same' },
'new Worker() with type=classic should always send the credentials ' +
'regardless of the credentials option (include).');
// Tests for classic worker dynamic imports.
credentials_test(
{ type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=classic should always send the credentials for ' +
'same-origin dynamic imports regardless of the credentials option ' +
'(default).');
credentials_test(
{ credentials: 'omit', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=classic should always send the credentials for ' +
'same-origin dynamic imports regardless of the credentials option (omit).');
credentials_test(
{ credentials: 'same-origin', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=classic should always send the credentials for ' +
'same-origin dynamic imports regardless of the credentials option ' +
'(same-origin).');
credentials_test(
{ credentials: 'include', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'same' },
'new Worker() with type=classic should always send the credentials for ' +
'same-origin dynamic imports regardless of the credentials option ' +
'(include).');
credentials_test(
{ type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=classic should never send the credentials for ' +
'cross-origin dynamic imports regardless of the credentials option ' +
'(default).');
credentials_test(
{ credentials: 'omit', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=classic should never send the credentials for ' +
'cross-origin dynamic imports regardless of the credentials option ' +
'(omit).');
credentials_test(
{ credentials: 'same-origin', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=classic should never send the credentials for ' +
'cross-origin dynamic imports regardless of the credentials option ' +
'(same-origin).');
credentials_test(
{ credentials: 'include', type: 'classic' },
{ fetchType: 'descendant-dynamic', origin: 'remote' },
'new Worker() with type=classic should never send the credentials for ' +
'cross-origin dynamic imports regardless of the credentials option ' +
'(include).');
</script>
Set-Cookie: COOKIE_NAME=COOKIE_VALUE
Set-Cookie: COOKIE_NAME=1
Access-Control-Allow-Credentials: true
......@@ -2,6 +2,7 @@ def main(request, response):
cookie = request.cookies.first("COOKIE_NAME", None)
response_headers = [("Content-Type", "text/javascript"),
("Access-Control-Allow-Origin", request.headers.get("Origin")),
("Access-Control-Allow-Credentials", "true")]
cookie_value = '';
......
// Import a remote origin script.
import('http://{{domains[www1]}}:{{ports[http][0]}}/workers/modules/resources/credentials.py');
// Import a remote origin script.
import 'http://{{domains[www1]}}:{{ports[http][0]}}/workers/modules/resources/credentials.py';
......@@ -53,7 +53,8 @@ class CORE_EXPORT ReferrerScriptInfo {
bool IsDefaultValue() const {
return base_url_.IsNull() &&
credentials_mode_ == network::mojom::FetchCredentialsMode::kOmit &&
credentials_mode_ ==
network::mojom::FetchCredentialsMode::kSameOrigin &&
nonce_.IsEmpty() && parser_state_ == kNotParserInserted;
}
......@@ -67,10 +68,10 @@ class CORE_EXPORT ReferrerScriptInfo {
const KURL base_url_;
// Spec: "referencing script's credentials mode"
// The default value is "omit" per:
// The default value is "same-origin" per:
// https://html.spec.whatwg.org/multipage/webappapis.html#default-classic-script-fetch-options
const network::mojom::FetchCredentialsMode credentials_mode_ =
network::mojom::FetchCredentialsMode::kOmit;
network::mojom::FetchCredentialsMode::kSameOrigin;
// Spec: "referencing script's cryptographic nonce"
const String nonce_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment