Commit d2c1d3d7 authored by Lily Chen's avatar Lily Chen Committed by Commit Bot

Port WebSocket 3p-cookie-blocking web tests to wpt_internal

(For context, see https://crrev.com/c/1691522.)

The new requirement that SameSite=None cookies must be Secure made it
impossible to properly test third party cookies on WebSocket because
the web_test runner does not have a wss server. This CL ports those
tests, formerly in web_tests/http/tests/security/cookies/websocket/,
to web_tests/wpt_internal/websocket-cookies/.

Bug: none
Change-Id: Ifc6d2d78a84aa6c93e297dc71b3595108a18f179
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1713670
Commit-Queue: Lily Chen <chlily@chromium.org>
Reviewed-by: default avatarRobert Ma <robertma@chromium.org>
Reviewed-by: default avatarAdam Rice <ricea@chromium.org>
Cr-Commit-Position: refs/heads/master@{#686071}
parent 14531a4e
// Set up global variables.
(_ => {
var HOST = '{{host}}';
var CROSS_ORIGIN_HOST = '{{hosts[alt][]}}';
var WSS_PORT = ':{{ports[wss][0]}}';
var HTTPS_PORT = ':{{ports[https][0]}}';
window.WSS_ORIGIN = 'wss://' + HOST + WSS_PORT;
window.WSS_CROSS_SITE_ORIGIN = 'wss://' + CROSS_ORIGIN_HOST + WSS_PORT;
window.HTTPS_ORIGIN = 'https://' + HOST + HTTPS_PORT;
window.HTTPS_CROSS_SITE_ORIGIN = 'https://' + CROSS_ORIGIN_HOST + HTTPS_PORT;
})();
// Sets a cookie with each SameSite option.
function setSameSiteCookies(origin, value) {
return new Promise(resolve => {
const ws = new WebSocket(origin + '/set-cookies-samesite?value=' + value);
ws.onopen = () => {
ws.close();
};
ws.onclose = resolve;
});
}
// Clears cookies set by setSameSiteCookies().
function clearSameSiteCookies(origin) {
return new Promise(resolve => {
const ws = new WebSocket(origin + '/set-cookies-samesite?clear');
ws.onopen = () => ws.close();
ws.onclose = resolve;
});
}
// Gets value of Cookie header sent in request.
function connectAndGetRequestCookiesFrom(origin) {
return new Promise((resolve, reject) => {
var ws = new WebSocket(origin + '/echo-cookie');
ws.onmessage = evt => {
var cookies = evt.data
resolve(cookies);
ws.onerror = undefined;
ws.onclose = undefined;
};
ws.onerror = () => reject('Unexpected error event');
ws.onclose = evt => reject('Unexpected close event: ' + JSON.stringify(evt));
});
}
// Assert that a given cookie is or is not present in the string |cookies|.
function assertCookie(cookies, name, value, present) {
var assertion = present ? assert_true : assert_false;
var description = name + '=' + value + ' cookie is' +
(present ? ' ' : ' not ') + 'present.';
var re = new RegExp('(?:^|; )' + name + '=' + value + '(?:$|;)');
assertion(re.test(cookies), description);
}
<!DOCTYPE html>
<meta charset="utf-8"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/websocket-cookies-helper.sub.js"></script>
<script>
promise_test(() => {
var value = '' + Math.random();
var origin = WSS_CROSS_SITE_ORIGIN;
return setSameSiteCookies(origin, value).then(
() => { return connectAndGetRequestCookiesFrom(origin); }
).then(
cookies => {
assert_not_equals(cookies, '(none)', 'request should contain cookies.');
// SameSite cookies are blocked.
assertCookie(cookies, 'samesite-unspecified', value, false /* present */);
assertCookie(cookies, 'samesite-lax', value, false /* present */);
assertCookie(cookies, 'samesite-strict', value, false /* present */);
// SameSite=None third-party cookie is not blocked.
assertCookie(cookies, 'samesite-none', value, true /* present */);
return clearSameSiteCookies(origin);
}
);
}, 'Test that third-party cookies are accepted for WebSockets.');
</script>
from six.moves import urllib
def web_socket_do_extra_handshake(request):
url_parts = urllib.parse.urlsplit(request.uri)
max_age = ""
if "clear" in url_parts.query:
max_age = "; Max-Age=0"
value = "1"
if "value" in url_parts.query:
value = urllib.parse.parse_qs(url_parts.query)["value"][0]
cookies = [
"samesite-unspecified={}; Path=/".format(value) + max_age,
"samesite-lax={}; Path=/; SameSite=Lax".format(value) + max_age,
"samesite-strict={}; Path=/; SameSite=Strict".format(value) + max_age,
# SameSite=None cookies must be Secure.
"samesite-none={}; Path=/; SameSite=None; Secure".format(value) + max_age
]
for cookie in cookies:
request.extra_headers.append(("Set-Cookie", cookie))
def web_socket_transfer_data(request):
# Expect close() from user agent.
request.ws_stream.receive_message()
These tests are for testing third party cookie blocking in conjunction with
WebSockets.
These tests were ported over from http/tests/security/cookies/websocket/.
They need to be here because secure WebSockets are required in order to use
SameSite=None cookies, and wptserve has a wss server but the regular web test
runner does not.
Also see external/wpt/websockets/cookies/third-party-cookie-accepted.https.html,
which would be part of this test suite but it doesn't need to use testRunner
(since it doesn't use third-party cookie blocking) so it can go in external/wpt.
<!DOCTYPE html>
<meta charset="utf-8"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/websockets/cookies/support/websocket-cookies-helper.sub.js"></script>
<script>
if (window.testRunner) {
// Block third-party cookies.
testRunner.setBlockThirdPartyCookies(true);
}
promise_test(() => {
var value = '' + Math.random();
var origin = WSS_ORIGIN;
return setSameSiteCookies(origin, value).then(
() => connectAndGetRequestCookiesFrom(origin)
).then(
cookies => {
assert_not_equals(cookies, '(none)', 'request should contain cookies.');
assertCookie(cookies, 'samesite-unspecified', value, true /* present */);
assertCookie(cookies, 'samesite-lax', value, true /* present */);
assertCookie(cookies, 'samesite-strict', value, true /* present */);
assertCookie(cookies, 'samesite-none', value, true /* present */);
return clearSameSiteCookies(origin);
}
);
}, 'Test that first-party cookies are not blocked for WebSockets.');
</script>
<!DOCTYPE html>
<script src="/websockets/cookies/support/websocket-cookies-helper.sub.js"></script>
<script>
function notifySuccess(value) {
window.parent.postMessage('DONE: ' + value, '*');
}
function notifyFailure(reason) {
window.parent.postMessage('FAIL: ' + reason, '*');
}
let origin = WSS_ORIGIN;
if (location.search == '?remote') {
origin = WSS_CROSS_SITE_ORIGIN;
}
setSameSiteCookies(origin, 'value').then(
() => connectAndGetRequestCookiesFrom(origin),
notifyFailure
).then(
cookies => {
return clearSameSiteCookies(origin).then(() => {
notifySuccess(cookies);
});
}
).catch(
notifyFailure
);
</script>
<!DOCTYPE html>
<meta charset="utf-8"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/websockets/cookies/support/websocket-cookies-helper.sub.js"></script>
<iframe id="iframe" src=""></iframe>
<script>
if (window.testRunner) {
// Block third-party cookies.
testRunner.setBlockThirdPartyCookies(true);
}
async_test(t => {
window.addEventListener(
'message',
t.step_func_done(event => {
assert_equals(event.data, 'DONE: (none)');
}),
false);
// The iframe is cross-origin from the websocket and from the main frame.
// The main frame is same-origin as the websocket.
var url = document.location.href.replace(HTTPS_ORIGIN, HTTPS_CROSS_SITE_ORIGIN)
.replace('third-party-cookie-blocked-on-cross-origin-websocket.https.html', '') +
'resources/set-cookie.https.html';
document.getElementById('iframe').setAttribute('src', url);
}, 'Test that first-party cookies are blocked for WebSockets conforming the ' +
'requirements of the SameSite attribute.');
</script>
<!DOCTYPE html>
<meta charset="utf-8"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/websockets/cookies/support/websocket-cookies-helper.sub.js"></script>
<iframe id="iframe" src=""></iframe>
<script>
if (window.testRunner) {
// Block third-party cookies.
testRunner.setBlockThirdPartyCookies(true);
}
async_test(t => {
window.addEventListener(
'message',
t.step_func_done(event => {
assert_equals(event.data, 'DONE: (none)');
}),
false);
// The iframe is same-origin as the websocket and cross-origin from the main frame.
// The main frame is cross-origin from the websocket.
var url = document.location.href.replace(HTTPS_ORIGIN, HTTPS_CROSS_SITE_ORIGIN)
.replace('third-party-cookie-blocked-on-same-origin-websocket.https.html', '') +
'resources/set-cookie.https.html?remote';
document.getElementById('iframe').setAttribute('src', url);
}, 'Test that third-party cookies are blocked for WebSockets even when the ' +
'WebSocket\'s URL\'s domain is an exact match for the domain of its ' +
'initiator.');
</script>
<!DOCTYPE html>
<meta charset="utf-8"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/websockets/cookies/support/websocket-cookies-helper.sub.js"></script>
<script>
if (window.testRunner) {
// Block third-party cookies.
testRunner.setBlockThirdPartyCookies(true);
}
promise_test(() => {
var value = '' + Math.random();
var origin = WSS_CROSS_SITE_ORIGIN;
return setSameSiteCookies(origin, value).then(
() => connectAndGetRequestCookiesFrom(origin)
).then(
cookies => {
assert_equals(cookies, '(none)', 'request should not contain cookies.');
return clearSameSiteCookies(origin);
}
);
}, 'Test third-party cookie blocking for WebSockets');
</script>
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