Cap lifetime of persistent cookies created client-side through document.cookie
authorwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 Sep 2018 01:13:26 +0000 (01:13 +0000)
committerwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 Sep 2018 01:13:26 +0000 (01:13 +0000)
commitbcb426d989211c6e17d92a146d17bd40b9ac3b8c
tree960ad2c00933ce0c9ba4bcf5ac8302e4753b3fcc
parent84804dd1e91d68598dacf1e257c4bd8878959743
Cap lifetime of persistent cookies created client-side through document.cookie
https://bugs.webkit.org/show_bug.cgi?id=189933
<rdar://problem/44741888>

Reviewed by Chris Dumez.

Source/WebCore:

Test: http/tests/cookies/capped-lifetime-for-cookie-set-in-js.html

As pointed out in https://github.com/mikewest/http-state-tokens:

1) Cookies are available to JavaScript by default via document.cookie, which
enables a smooth upgrade from one-time XSS to theft of persistent credentials
and also makes cookies available to Spectre-like attacks on memory.

2) Though the HttpOnly attribute was introduced well over a decade ago, only
~8.31% of Set-Cookie operations use it today (stats from Chrome). We need
developer incentives to put proper protections in place.

3) The median (uncompressed) Cookie request header is 409 bytes, while the 90th
percentile is 1,589 bytes, the 95th 2,549 bytes, the 99th 4,601 bytes, and
~0.1% of Cookie headers are over 10kB (stats from Chrome). This is bad for load
performance.

In addition to this, third-party scripts running in first-party contexts can
read user data through document.cookie and even store cross-site tracking data
in them.

Authentication cookies should be HttpOnly and thus not be affected by
restrictions to document.cookie. Cookies that persist for a long time should
be Secure, HttpOnly, and SameSite to provide good security and privacy.

By capping the lifetime of persistent cookies set through document.cookie we
embark on a journey towards better cookie management on the web.

* platform/network/cocoa/NetworkStorageSessionCocoa.mm:
(WebCore::filterCookies):
    Now caps the life time of persistent cookies to one week (seven days).
* testing/Internals.cpp:
(WebCore::Internals::getCookies const):
    New test function to get to cookie meta data such as expiry.
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

* TestExpectations:
    Skipped the new test by default since the behavior change is for
    Cocoa platforms only.
* http/tests/cookies/capped-lifetime-for-cookie-set-in-js-expected.txt: Added.
* http/tests/cookies/capped-lifetime-for-cookie-set-in-js.html: Added.
* http/tests/cookies/resources/cookie-utilities.js:
* platform/ios/TestExpectations:
    Marked the new test as [ Pass ].
* platform/mac-wk2/TestExpectations:
    Marked the new test as [ Pass ].

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236448 268f45cc-cd09-0410-ab3c-d52691b4dbfc
12 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/http/tests/cookies/capped-lifetime-for-cookie-set-in-js-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/cookies/capped-lifetime-for-cookie-set-in-js.html [new file with mode: 0644]
LayoutTests/http/tests/cookies/resources/cookie-utilities.js
LayoutTests/platform/ios/TestExpectations
LayoutTests/platform/mac-wk2/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl