Flesh out WebSocket cookie tests to cover cookie policy for third-party resources
authorwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Jul 2018 01:07:38 +0000 (01:07 +0000)
committerwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Jul 2018 01:07:38 +0000 (01:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187541
<rdar://problem/42048729>

Reviewed by Alex Christensen.

* http/tests/cookies/resources/cookie-utilities.js:
    Added a function for setting a cookie in a WebSocket handshake.
* http/tests/websocket/tests/hybi/cookie_wsh.py:
(web_socket_do_extra_handshake):
    Now sets the root path for new cookies so that they can be seen by
    for example cookies/resources/echo-cookies.php.
* http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party-expected.txt: Added.
* http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party.html: Added.
* http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party-expected.txt: Added.
* http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party.html: Added.
* http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior-expected.txt:
* http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior.html:
    Now tests under the condition where localhost as third-party is
    allowed to set a new cookie as third party. It also makes sure to use
    cookies with the path set to the root so that all cookies are visible.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233830 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/cookies/resources/cookie-utilities.js
LayoutTests/http/tests/websocket/tests/hybi/cookie_wsh.py
LayoutTests/http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party.html [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party.html [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior-expected.txt
LayoutTests/http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior.html

index eab3681..35b2eb5 100644 (file)
@@ -1,3 +1,27 @@
+2018-07-13  John Wilander  <wilander@apple.com>
+
+        Flesh out WebSocket cookie tests to cover cookie policy for third-party resources
+        https://bugs.webkit.org/show_bug.cgi?id=187541
+        <rdar://problem/42048729>
+
+        Reviewed by Alex Christensen.
+
+        * http/tests/cookies/resources/cookie-utilities.js:
+            Added a function for setting a cookie in a WebSocket handshake.
+        * http/tests/websocket/tests/hybi/cookie_wsh.py:
+        (web_socket_do_extra_handshake):
+            Now sets the root path for new cookies so that they can be seen by
+            for example cookies/resources/echo-cookies.php.
+        * http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party.html: Added.
+        * http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party.html: Added.
+        * http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior-expected.txt:
+        * http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior.html:
+            Now tests under the condition where localhost as third-party is
+            allowed to set a new cookie as third party. It also makes sure to use
+            cookies with the path set to the root so that all cookies are visible.
+
 2018-07-13  Youenn Fablet  <youenn@apple.com>
 
         Support connecting a MediaStreamAudioDestinationNode to RTCPeerConnection
index 51b5ab6..0b8fb34 100644 (file)
@@ -228,3 +228,12 @@ function shouldHaveDOMCookieWithValue(name, expectedValue)
     else
         testFailed(`DOM cookie "${name}" should have value ${expectedValue}. Was ${value}.`);
 }
+
+function setCookieUsingWebSocketFromHost(host)
+{
+    var promise = new Promise(resolve => {
+        var websocket = new WebSocket(`ws://${host}:8880/websocket/tests/hybi/cookie?set`);
+        websocket.onclose = () => resolve();
+    });
+    return promise;
+}
index 69b6a0e..aa08d51 100644 (file)
@@ -1,4 +1,5 @@
 # Copyright (C) 2014 Google Inc. All rights reserved.
+# Copyright (C) 2018 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
@@ -38,12 +39,13 @@ def web_socket_do_extra_handshake(request):
     command = components[4]
 
     ONE_DAY_LIFE = 'Max-Age=86400'
+    ROOT_PATH = 'path=/'
 
     if command == 'set':
-        _add_set_cookie(request, '; '.join(['foo=bar', ONE_DAY_LIFE]))
+        _add_set_cookie(request, '; '.join(['foo=bar', ONE_DAY_LIFE, ROOT_PATH]))
     elif command == 'set_httponly':
         _add_set_cookie(request,
-            '; '.join(['httpOnlyFoo=bar', ONE_DAY_LIFE, 'httpOnly']))
+            '; '.join(['httpOnlyFoo=bar', ONE_DAY_LIFE, ROOT_PATH, 'httpOnly']))
     elif command == 'clear':
         _add_set_cookie(request, 'foo=0; Max-Age=0')
         _add_set_cookie(request, 'httpOnlyFoo=0; Max-Age=0')
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party-expected.txt b/LayoutTests/http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party-expected.txt
new file mode 100644 (file)
index 0000000..d456f49
--- /dev/null
@@ -0,0 +1,19 @@
+Tests WebSocket Set-Cookie behavior for third-parties with existing cookies.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.location.host is "127.0.0.1:8000"
+
+Setting third-party cookie 'foo' through cross-origin WebSocket handshake.
+
+Opening localhost third-party iframe to check its cookies.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--frame1-->'
+--------
+Cookies are: setAsFirstParty = value foo = bar
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party.html b/LayoutTests/http/tests/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party.html
new file mode 100644 (file)
index 0000000..28bb549
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="../../../../js-test-resources/js-test.js"></script>
+    <script src="../../../cookies/resources/cookie-utilities.js"></script>
+    <script>
+        window.jsTestIsAsync = true;
+
+        async function testThirdPartyCookie()
+        {
+            shouldBeEqualToString("document.location.host", "127.0.0.1:8000");
+            debug("<br>Setting third-party cookie 'foo' through cross-origin WebSocket handshake.");
+            await setCookieUsingWebSocketFromHost("localhost");
+            let iframeElement = document.createElement("iframe");
+            iframeElement.src = "http://localhost:8000/cookies/resources/echo-cookies.php";
+            iframeElement.onload = finishJSTest;
+            debug("<br>Opening localhost third-party iframe to check its cookies.");
+            document.body.appendChild(iframeElement);
+        }
+
+        async function runTest()
+        {
+            switch (document.location.hash) {
+                case "":
+                    // Navigate to localhost to set first-party cookie 'setAsFirstParty'.
+                    document.location.href = "http://localhost:8000/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party.html#setCookieAsFirstParty";
+                    break;
+                case "#setCookieAsFirstParty":
+                    await setCookie("setAsFirstParty", "value");
+                    // Navigate back to 127.0.0.1 to test third-party cookie.
+                    document.location.href = "http://127.0.0.1:8000/websocket/tests/hybi/websocket-allowed-setting-cookie-as-third-party.html#didSetCookieAsFirstParty";
+                    break;
+                case "#didSetCookieAsFirstParty":
+                    testRunner.dumpChildFramesAsText();
+                    await testThirdPartyCookie();
+                    break;
+            }
+        }
+    </script>
+</head>
+<body>
+<div id="output"></div>
+<script>
+    description("Tests WebSocket Set-Cookie behavior for third-parties with existing cookies.");
+    runTest();
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party-expected.txt b/LayoutTests/http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party-expected.txt
new file mode 100644 (file)
index 0000000..bc74b81
--- /dev/null
@@ -0,0 +1,19 @@
+Tests WebSocket Set-Cookie behavior for third-parties without existing cookies.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.location.host is "127.0.0.1:8000"
+
+Attempting to set third-party cookie 'foo' through cross-origin WebSocket handshake.
+
+Opening localhost third-party iframe to check its cookies.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--frame1-->'
+--------
+Cookies are:
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party.html b/LayoutTests/http/tests/websocket/tests/hybi/websocket-blocked-from-setting-cookie-as-third-party.html
new file mode 100644 (file)
index 0000000..82a8648
--- /dev/null
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="../../../../js-test-resources/js-test.js"></script>
+    <script src="../../../cookies/resources/cookie-utilities.js"></script>
+    <script>
+        window.jsTestIsAsync = true;
+
+        async function runTest()
+        {
+            testRunner.dumpChildFramesAsText();
+            shouldBeEqualToString("document.location.host", "127.0.0.1:8000");
+            debug("<br>Attempting to set third-party cookie 'foo' through cross-origin WebSocket handshake.");
+            await setCookieUsingWebSocketFromHost("localhost");
+            let iframeElement = document.createElement("iframe");
+            iframeElement.src = "http://localhost:8000/cookies/resources/echo-cookies.php";
+            iframeElement.onload = finishJSTest;
+            debug("<br>Opening localhost third-party iframe to check its cookies.");
+            document.getElementById("output").appendChild(iframeElement);
+        }
+    </script>
+</head>
+<body>
+<div id="output"></div>
+<script>
+    description("Tests WebSocket Set-Cookie behavior for third-parties without existing cookies.");
+    runTest();
+</script>
+</body>
+</html>
index e9b1ad7..e86d011 100644 (file)
@@ -3,12 +3,16 @@ Tests WebSocket Set-Cookie overwriting behavior with respect to a document cooki
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-Same origin WebSocket:
-PASS cookieValue is "foo=bar"
-
-Cross origin WebSocket:
+Setting third-party cookie 'foo' through cross-origin WebSocket handshake and checking that it doesn't write first-party cookies.
 PASS cookieValue is ""
+
+Opening localhost third-party iframe to check its cookies.
 PASS successfullyParsed is true
 
 TEST COMPLETE
 
+
+--------
+Frame: '<!--frame1-->'
+--------
+Cookies are: setAsFirstParty = value foo = bar
index ac4f749..19c0b5d 100644 (file)
@@ -2,6 +2,7 @@
 <html>
 <head>
 <script src="../../../../js-test-resources/js-test.js"></script>
+<script src="../../../cookies/resources/cookie-utilities.js"></script>
 <script>
 window.jsTestIsAsync = true;
 
@@ -9,16 +10,7 @@ var cookieValue;
 
 function clearCookie()
 {
-    document.cookie = "foo=0; Max-Age=0"; // The key "foo" must match the key used in the WebSocket Set-Cookie header.
-}
-
-function setCookieFromHost(host)
-{
-    var promise = new Promise(resolve => {
-        var websocket = new WebSocket(`ws://${host}:8880/websocket/tests/hybi/cookie?set`);
-        websocket.onclose = () => resolve();
-    });
-    return promise;
+    document.cookie = "foo=0; Max-Age=0; path=/"; // The key "foo" must match the key used in the WebSocket Set-Cookie header.
 }
 
 function echoCookie()
@@ -29,8 +21,8 @@ function echoCookie()
 async function testSameOriginCookie()
 {
     clearCookie();
-    document.cookie = "foo=should_be_overwritten_by_websocket_set_cookie";
-    await setCookieFromHost("127.0.0.1");
+    document.cookie = "foo=should_be_overwritten_by_websocket_set_cookie; path=/";
+    await setCookieUsingWebSocketFromHost("127.0.0.1");
     cookieValue = echoCookie();
     shouldBeEqualToString("cookieValue", "foo=bar");
 }
@@ -38,18 +30,38 @@ async function testSameOriginCookie()
 async function testCrossOriginCookie()
 {
     clearCookie();
-    await setCookieFromHost("localhost");
+    await setCookieUsingWebSocketFromHost("localhost");
     cookieValue = echoCookie();
     shouldBeEmptyString("cookieValue");
 }
 
 async function runTests()
 {
-    debug("Same origin WebSocket:");
-    await testSameOriginCookie();
-    debug("<br>Cross origin WebSocket:");
-    await testCrossOriginCookie();
-    finishJSTest();
+    switch (document.location.hash) {
+        case "":
+            await testSameOriginCookie();
+            // Test that a third-party without pre-existing cookies does not write first-party cookies.
+            await testCrossOriginCookie();
+            // Navigate to localhost to set first-party cookie 'setAsFirstParty'.
+            document.location.href = "http://localhost:8000/websocket/tests/hybi/websocket-cookie-overwrite-behavior.html#setCookieAsFirstParty";
+            break;
+        case "#setCookieAsFirstParty":
+            await setCookie("setAsFirstParty", "value");
+            // Navigate back to 127.0.0.1 to test third-party cookie.
+            document.location.href = "http://127.0.0.1:8000/websocket/tests/hybi/websocket-cookie-overwrite-behavior.html#didSetCookieAsFirstParty";
+            break;
+        case "#didSetCookieAsFirstParty":
+            testRunner.dumpChildFramesAsText();
+            // Test that a third-party with a pre-existing cookie does not write first-party cookies.
+            debug("Setting third-party cookie 'foo' through cross-origin WebSocket handshake and checking that it doesn't write first-party cookies.");
+            await testCrossOriginCookie();
+            let iframeElement = document.createElement("iframe");
+            iframeElement.src = "http://localhost:8000/cookies/resources/echo-cookies.php";
+            iframeElement.onload = finishJSTest;
+            debug("<br>Opening localhost third-party iframe to check its cookies.");
+            document.body.appendChild(iframeElement);
+            break;
+    }
 }
 </script>
 </head>