Web Inspector: SameSite parsing should be stricter
authorpecoraro@apple.com <pecoraro@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Apr 2019 21:53:48 +0000 (21:53 +0000)
committerpecoraro@apple.com <pecoraro@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Apr 2019 21:53:48 +0000 (21:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196927
<rdar://problem/42291601>

Reviewed by Devin Rousso.

Source/WebInspectorUI:

* UserInterface/Models/Cookie.js:
(WI.Cookie.parseSameSiteAttributeValue):

LayoutTests:

* inspector/unit-tests/cookie.html:
* inspector/unit-tests/cookie-expected.txt:

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

LayoutTests/ChangeLog
LayoutTests/inspector/unit-tests/cookie-expected.txt
LayoutTests/inspector/unit-tests/cookie.html
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Models/Cookie.js

index 0bd7203..8f51023 100644 (file)
@@ -1,3 +1,14 @@
+2019-04-15  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: SameSite parsing should be stricter
+        https://bugs.webkit.org/show_bug.cgi?id=196927
+        <rdar://problem/42291601>
+
+        Reviewed by Devin Rousso.
+
+        * inspector/unit-tests/cookie.html:
+        * inspector/unit-tests/cookie-expected.txt:
+
 2019-04-15  John Wilander  <wilander@apple.com>
 
         Send delayed Ad Click Attribution conversion requests to the click source
index 681f7d1..301a0c0 100644 (file)
@@ -54,6 +54,7 @@ PASS: cookie.path should be 'null'.
 PASS: cookie.domain should be 'null'.
 PASS: cookie.secure should be 'false'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=value; path=/foo
 PASS: Value should be a WI.Cookie.
@@ -67,6 +68,7 @@ PASS: cookie.path should be '/foo'.
 PASS: cookie.domain should be 'null'.
 PASS: cookie.secure should be 'false'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=value; domain=example.com
 PASS: Value should be a WI.Cookie.
@@ -80,6 +82,7 @@ PASS: cookie.path should be 'null'.
 PASS: cookie.domain should be 'example.com'.
 PASS: cookie.secure should be 'false'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=value; secure
 PASS: Value should be a WI.Cookie.
@@ -93,6 +96,7 @@ PASS: cookie.path should be 'null'.
 PASS: cookie.domain should be 'null'.
 PASS: cookie.secure should be 'true'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=value; Secure
 PASS: Value should be a WI.Cookie.
@@ -106,6 +110,7 @@ PASS: cookie.path should be 'null'.
 PASS: cookie.domain should be 'null'.
 PASS: cookie.secure should be 'true'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=value; HttpOnly
 PASS: Value should be a WI.Cookie.
@@ -119,6 +124,63 @@ PASS: cookie.path should be 'null'.
 PASS: cookie.domain should be 'null'.
 PASS: cookie.secure should be 'false'.
 PASS: cookie.httpOnly should be 'true'.
+PASS: cookie.sameSite should be 'None'.
+
+HEADER: Set-Cookie: name=value; SameSite=lax
+PASS: Value should be a WI.Cookie.
+PASS: cookie.header should be the original header text.
+PASS: cookie.type should be WI.Cookie.Type.Response.
+PASS: cookie.name should be 'name'.
+PASS: cookie.value should be 'value'.
+PASS: cookie.expires should be 'null'.
+PASS: cookie.maxAge should be 'null'.
+PASS: cookie.path should be 'null'.
+PASS: cookie.domain should be 'null'.
+PASS: cookie.secure should be 'false'.
+PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'Lax'.
+
+HEADER: Set-Cookie: name=value; SameSite=strict
+PASS: Value should be a WI.Cookie.
+PASS: cookie.header should be the original header text.
+PASS: cookie.type should be WI.Cookie.Type.Response.
+PASS: cookie.name should be 'name'.
+PASS: cookie.value should be 'value'.
+PASS: cookie.expires should be 'null'.
+PASS: cookie.maxAge should be 'null'.
+PASS: cookie.path should be 'null'.
+PASS: cookie.domain should be 'null'.
+PASS: cookie.secure should be 'false'.
+PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'Strict'.
+
+HEADER: Set-Cookie: name=value; SameSite=invalid
+PASS: Value should be a WI.Cookie.
+PASS: cookie.header should be the original header text.
+PASS: cookie.type should be WI.Cookie.Type.Response.
+PASS: cookie.name should be 'name'.
+PASS: cookie.value should be 'value'.
+PASS: cookie.expires should be 'null'.
+PASS: cookie.maxAge should be 'null'.
+PASS: cookie.path should be 'null'.
+PASS: cookie.domain should be 'null'.
+PASS: cookie.secure should be 'false'.
+PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
+
+HEADER: Set-Cookie: name=value; SameSite
+PASS: Value should be a WI.Cookie.
+PASS: cookie.header should be the original header text.
+PASS: cookie.type should be WI.Cookie.Type.Response.
+PASS: cookie.name should be 'name'.
+PASS: cookie.value should be 'value'.
+PASS: cookie.expires should be 'null'.
+PASS: cookie.maxAge should be 'null'.
+PASS: cookie.path should be 'null'.
+PASS: cookie.domain should be 'null'.
+PASS: cookie.secure should be 'false'.
+PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=value; expires=Fri 06-Oct-2017 03:20:27 GMT; Max-Age=3600
 PASS: Value should be a WI.Cookie.
@@ -132,6 +194,7 @@ PASS: cookie.path should be 'null'.
 PASS: cookie.domain should be 'null'.
 PASS: cookie.secure should be 'false'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=value; expires=Fri 06-Oct-2017 03:43:47 GMT; Max-Age=5000; path=/foo; domain=example.com; secure; HttpOnly
 PASS: Value should be a WI.Cookie.
@@ -145,6 +208,7 @@ PASS: cookie.path should be '/foo'.
 PASS: cookie.domain should be 'example.com'.
 PASS: cookie.secure should be 'true'.
 PASS: cookie.httpOnly should be 'true'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=value; Unknown; path=/one/two
 WARN: Unknown Cookie attribute: Unknown
@@ -159,6 +223,7 @@ PASS: cookie.path should be '/one/two'.
 PASS: cookie.domain should be 'null'.
 PASS: cookie.secure should be 'false'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=value; Unknown=Ignored; path=/one/two
 WARN: Unknown Cookie attribute: Unknown=Ignored
@@ -173,6 +238,7 @@ PASS: cookie.path should be '/one/two'.
 PASS: cookie.domain should be 'null'.
 PASS: cookie.secure should be 'false'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name=somewhat longer value than normal with spaces, and commas; domain=other.example.com
 PASS: Value should be a WI.Cookie.
@@ -186,6 +252,7 @@ PASS: cookie.path should be 'null'.
 PASS: cookie.domain should be 'other.example.com'.
 PASS: cookie.secure should be 'false'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 HEADER: Set-Cookie: name==value=;Domain=.example.com;Expires=Wed, 04-Apr-2018 03:34:02 GMT
 PASS: Value should be a WI.Cookie.
@@ -199,6 +266,7 @@ PASS: cookie.path should be 'null'.
 PASS: cookie.domain should be '.example.com'.
 PASS: cookie.secure should be 'false'.
 PASS: cookie.httpOnly should be 'false'.
+PASS: cookie.sameSite should be 'None'.
 
 
 -- Running test case: WI.Cookie.url
index d0d0423..3e160c9 100644 (file)
@@ -68,6 +68,7 @@ function test()
                 InspectorTest.expectEqual(cookie.domain, expected.domain, `cookie.domain should be '${expected.domain}'.`);
                 InspectorTest.expectEqual(cookie.secure, expected.secure, `cookie.secure should be '${expected.secure}'.`);
                 InspectorTest.expectEqual(cookie.httpOnly, expected.httpOnly, `cookie.httpOnly should be '${expected.httpOnly}'.`);
+                InspectorTest.expectEqual(cookie.sameSite, expected.sameSite, `cookie.sameSite should be '${expected.sameSite}'.`);
                 InspectorTest.log("");
             }
 
@@ -82,6 +83,7 @@ function test()
                 domain: null,
                 secure: false,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=value; path=/foo`, {
@@ -93,6 +95,7 @@ function test()
                 domain: null,
                 secure: false,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=value; domain=example.com`, {
@@ -104,6 +107,7 @@ function test()
                 domain: "example.com",
                 secure: false,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=value; secure`, {
@@ -115,6 +119,7 @@ function test()
                 domain: null,
                 secure: true,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=value; Secure`, {
@@ -126,6 +131,7 @@ function test()
                 domain: null,
                 secure: true,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=value; HttpOnly`, {
@@ -137,6 +143,57 @@ function test()
                 domain: null,
                 secure: false,
                 httpOnly: true,
+                sameSite: WI.Cookie.SameSiteType.None,
+            });
+
+            test(`name=value; SameSite=lax`, {
+                name: "name",
+                value: "value",
+                expires: null,
+                maxAge: null,
+                path: null,
+                domain: null,
+                secure: false,
+                httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.Lax,
+            });
+
+            test(`name=value; SameSite=strict`, {
+                name: "name",
+                value: "value",
+                expires: null,
+                maxAge: null,
+                path: null,
+                domain: null,
+                secure: false,
+                httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.Strict,
+            });
+
+            // SameSite with unknown value is ignored.
+            test(`name=value; SameSite=invalid`, {
+                name: "name",
+                value: "value",
+                expires: null,
+                maxAge: null,
+                path: null,
+                domain: null,
+                secure: false,
+                httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
+            });
+
+            // SameSite without value is ignored.
+            test(`name=value; SameSite`, {
+                name: "name",
+                value: "value",
+                expires: null,
+                maxAge: null,
+                path: null,
+                domain: null,
+                secure: false,
+                httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=value; expires=Fri 06-Oct-2017 03:20:27 GMT; Max-Age=3600`, {
@@ -148,6 +205,7 @@ function test()
                 domain: null,
                 secure: false,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=value; expires=Fri 06-Oct-2017 03:43:47 GMT; Max-Age=5000; path=/foo; domain=example.com; secure; HttpOnly`, {
@@ -159,6 +217,7 @@ function test()
                 domain: "example.com",
                 secure: true,
                 httpOnly: true,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=value; Unknown; path=/one/two`, {
@@ -170,6 +229,7 @@ function test()
                 domain: null,
                 secure: false,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=value; Unknown=Ignored; path=/one/two`, {
@@ -181,6 +241,7 @@ function test()
                 domain: null,
                 secure: false,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             test(`name=somewhat longer value than normal with spaces, and commas; domain=other.example.com`, {
@@ -192,6 +253,7 @@ function test()
                 domain: "other.example.com",
                 secure: false,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             // Some servers omit the required space after the semicolon.
@@ -204,6 +266,7 @@ function test()
                 domain: ".example.com",
                 secure: false,
                 httpOnly: false,
+                sameSite: WI.Cookie.SameSiteType.None,
             });
 
             return true;
index 963c116..cdc1ab5 100644 (file)
@@ -1,5 +1,16 @@
 2019-04-15  Joseph Pecoraro  <pecoraro@apple.com>
 
+        Web Inspector: SameSite parsing should be stricter
+        https://bugs.webkit.org/show_bug.cgi?id=196927
+        <rdar://problem/42291601>
+
+        Reviewed by Devin Rousso.
+
+        * UserInterface/Models/Cookie.js:
+        (WI.Cookie.parseSameSiteAttributeValue):
+
+2019-04-15  Joseph Pecoraro  <pecoraro@apple.com>
+
         Web Inspector: CPU Usage Timeline - Energy impact popover flickers
         https://bugs.webkit.org/show_bug.cgi?id=196931
         <rdar://problem/49569122>
index 04bb22e..50c95de 100644 (file)
@@ -114,18 +114,20 @@ WI.Cookie = class Cookie
         }
     }
 
-    // Derived from <https://tools.ietf.org/html/draft-west-first-party-cookies-06#section-3.2>.
+    // <https://httpwg.org/http-extensions/rfc6265bis.html#the-samesite-attribute-1>
     static parseSameSiteAttributeValue(attributeValue)
     {
         if (!attributeValue)
-            return WI.Cookie.SameSiteType.Strict;
+            return WI.Cookie.SameSiteType.None;
+
         switch (attributeValue.toLowerCase()) {
         case "lax":
             return WI.Cookie.SameSiteType.Lax;
         case "strict":
-        default:
             return WI.Cookie.SameSiteType.Strict;
         }
+
+        return WI.Cookie.SameSiteType.None;
     }
 
     static parseSetCookieResponseHeader(header)