Title: [242517] trunk
Revision
242517
Author
commit-qu...@webkit.org
Date
2019-03-05 15:36:56 -0800 (Tue, 05 Mar 2019)

Log Message

[Curl] Implement Cookie Accept Policy.
https://bugs.webkit.org/show_bug.cgi?id=191645

Patch by Takashi Komori <takashi.kom...@sony.com> on 2019-03-05
Reviewed by Fujii Hironori.

Source/WebCore:

Make Curl network layer respect to coookie accept policy.
This patch fixes tests below on TestRunner, but doesn't fix tests on DumpRenderTree.

Tests: http/tests/cookies/only-accept-first-party-cookies.html
       http/tests/cookies/third-party-cookie-relaxing.html
       http/tests/security/cookies/third-party-cookie-blocking-redirect.html
       http/tests/security/cookies/third-party-cookie-blocking-user-action.html
       http/tests/security/cookies/third-party-cookie-blocking-xslt.xml
       http/tests/security/cookies/third-party-cookie-blocking.html

* platform/network/curl/CookieJarCurl.cpp:
(WebCore::cookiesForSession):
(WebCore::CookieJarCurl::setCookiesFromDOM const):
(WebCore::CookieJarCurl::setCookiesFromHTTPResponse const):
(WebCore::CookieJarCurl::setCookieAcceptPolicy const):
(WebCore::CookieJarCurl::cookieAcceptPolicy const):
(WebCore::CookieJarCurl::getRawCookies const):
* platform/network/curl/CookieJarCurl.h:
* platform/network/curl/CookieJarDB.cpp:
(WebCore::CookieJarDB::openDatabase):
(WebCore::CookieJarDB::isEnabled const):
(WebCore::CookieJarDB::checkCookieAcceptPolicy):
(WebCore::CookieJarDB::hasCookies):
(WebCore::CookieJarDB::searchCookies):
(WebCore::CookieJarDB::canAcceptCookie):
(WebCore::CookieJarDB::setCookie):
(WebCore::CookieJarDB::setEnabled): Deleted.
* platform/network/curl/CookieJarDB.h:
(WebCore::CookieJarDB::setAcceptPolicy):
(WebCore::CookieJarDB::acceptPolicy const):
* platform/network/curl/CookieUtil.cpp:
(WebCore::CookieUtil::parseCookieAttributes):
(WebCore::CookieUtil::parseCookieHeader):
* platform/network/curl/CurlResourceHandleDelegate.cpp:
(WebCore::handleCookieHeaders):
(WebCore::CurlResourceHandleDelegate::curlDidReceiveResponse):

Source/WebKit:

* NetworkProcess/Cookies/curl/WebCookieManagerCurl.cpp:
(WebKit::WebCookieManager::platformSetHTTPCookieAcceptPolicy):
(WebKit::WebCookieManager::platformGetHTTPCookieAcceptPolicy):
* NetworkProcess/curl/NetworkDataTaskCurl.cpp:
(WebKit::NetworkDataTaskCurl::curlDidReceiveResponse):
(WebKit::NetworkDataTaskCurl::handleCookieHeaders):
* NetworkProcess/curl/NetworkDataTaskCurl.h:

Tools:

* TestWebKitAPI/Tests/WebCore/curl/Cookies.cpp:
(TestWebKitAPI::Curl::TEST_F):

LayoutTests:

* platform/wincairo-wk1/TestExpectations:
* platform/wincairo/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (242516 => 242517)


--- trunk/LayoutTests/ChangeLog	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/LayoutTests/ChangeLog	2019-03-05 23:36:56 UTC (rev 242517)
@@ -1,3 +1,13 @@
+2019-03-05  Takashi Komori  <takashi.kom...@sony.com>
+
+        [Curl] Implement Cookie Accept Policy.
+        https://bugs.webkit.org/show_bug.cgi?id=191645
+
+        Reviewed by Fujii Hironori.
+
+        * platform/wincairo-wk1/TestExpectations:
+        * platform/wincairo/TestExpectations:
+
 2019-03-05  Said Abou-Hallawa  <sabouhall...@apple.com>
 
         SVGPathSegList.insertItemBefore() should fail if the newItem belongs to an animating animPathSegList

Modified: trunk/LayoutTests/platform/wincairo/TestExpectations (242516 => 242517)


--- trunk/LayoutTests/platform/wincairo/TestExpectations	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/LayoutTests/platform/wincairo/TestExpectations	2019-03-05 23:36:56 UTC (rev 242517)
@@ -862,6 +862,7 @@
 http/tests/cookies/http-get-cookie-set-in-js.html [ Pass Failure ]
 http/tests/cookies/multiple-cookies.html [ Pass Failure ]
 http/tests/cookies/multiple-redirect-and-set-cookie.php [ Pass Failure ]
+http/tests/cookies/only-accept-first-party-cookies.html [ Pass ]
 http/tests/cookies/private-cookie-storage.html [ Skip ]
 http/tests/cookies/same-site [ Skip ]
 http/tests/cookies/set-cookie-on-redirect.html [ Pass Failure ]
@@ -869,7 +870,6 @@
 http/tests/cookies/simple-cookies-max-age.html [ Pass Failure ]
 http/tests/cookies/single-quoted-value.html [ Pass Failure ]
 http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html [ Pass Failure ]
-http/tests/cookies/third-party-cookie-relaxing.html [ Failure ]
 
 [ Debug ] http/tests/cookies/js-get-and-set-http-only-cookie.html [ Skip ]
 
@@ -939,6 +939,10 @@
 
 http/tests/security [ Skip ]
 http/tests/security/401-logout/401-logout.php [ Pass ]
+http/tests/security/cookies/third-party-cookie-blocking.html [ Pass ]
+http/tests/security/cookies/third-party-cookie-blocking-redirect.html [ Pass ]
+http/tests/security/cookies/third-party-cookie-blocking-user-action.html [ Pass ]
+http/tests/security/cookies/third-party-cookie-blocking-xslt.xml [ Pass ]
 
 http/tests/ssl [ Skip ]
 

Modified: trunk/LayoutTests/platform/wincairo-wk1/TestExpectations (242516 => 242517)


--- trunk/LayoutTests/platform/wincairo-wk1/TestExpectations	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/LayoutTests/platform/wincairo-wk1/TestExpectations	2019-03-05 23:36:56 UTC (rev 242517)
@@ -12,5 +12,13 @@
 
 # Failures on WebKit Legacy
 
+# Cookie policy only supported in WK2.
+http/tests/cookies/only-accept-first-party-cookies.html [ Skip ]
+http/tests/cookies/third-party-cookie-relaxing.html [ Skip ]
+http/tests/security/cookies/third-party-cookie-blocking.html [ Skip ]
+http/tests/security/cookies/third-party-cookie-blocking-redirect.html [ Skip ]
+http/tests/security/cookies/third-party-cookie-blocking-user-action.html [ Skip ]
+http/tests/security/cookies/third-party-cookie-blocking-xslt.xml [ Skip ]
+
 # There is not NetworkProcess in WK1, so it can't crash.
 http/tests/websocket/tests/hybi/network-process-crash-error.html [ Skip ]

Modified: trunk/Source/WebCore/ChangeLog (242516 => 242517)


--- trunk/Source/WebCore/ChangeLog	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebCore/ChangeLog	2019-03-05 23:36:56 UTC (rev 242517)
@@ -1,3 +1,47 @@
+2019-03-05  Takashi Komori  <takashi.kom...@sony.com>
+
+        [Curl] Implement Cookie Accept Policy.
+        https://bugs.webkit.org/show_bug.cgi?id=191645
+
+        Reviewed by Fujii Hironori.
+
+        Make Curl network layer respect to coookie accept policy.
+        This patch fixes tests below on TestRunner, but doesn't fix tests on DumpRenderTree.
+
+        Tests: http/tests/cookies/only-accept-first-party-cookies.html
+               http/tests/cookies/third-party-cookie-relaxing.html
+               http/tests/security/cookies/third-party-cookie-blocking-redirect.html
+               http/tests/security/cookies/third-party-cookie-blocking-user-action.html
+               http/tests/security/cookies/third-party-cookie-blocking-xslt.xml
+               http/tests/security/cookies/third-party-cookie-blocking.html
+
+        * platform/network/curl/CookieJarCurl.cpp:
+        (WebCore::cookiesForSession):
+        (WebCore::CookieJarCurl::setCookiesFromDOM const):
+        (WebCore::CookieJarCurl::setCookiesFromHTTPResponse const):
+        (WebCore::CookieJarCurl::setCookieAcceptPolicy const):
+        (WebCore::CookieJarCurl::cookieAcceptPolicy const):
+        (WebCore::CookieJarCurl::getRawCookies const):
+        * platform/network/curl/CookieJarCurl.h:
+        * platform/network/curl/CookieJarDB.cpp:
+        (WebCore::CookieJarDB::openDatabase):
+        (WebCore::CookieJarDB::isEnabled const):
+        (WebCore::CookieJarDB::checkCookieAcceptPolicy):
+        (WebCore::CookieJarDB::hasCookies):
+        (WebCore::CookieJarDB::searchCookies):
+        (WebCore::CookieJarDB::canAcceptCookie):
+        (WebCore::CookieJarDB::setCookie):
+        (WebCore::CookieJarDB::setEnabled): Deleted.
+        * platform/network/curl/CookieJarDB.h:
+        (WebCore::CookieJarDB::setAcceptPolicy):
+        (WebCore::CookieJarDB::acceptPolicy const):
+        * platform/network/curl/CookieUtil.cpp:
+        (WebCore::CookieUtil::parseCookieAttributes):
+        (WebCore::CookieUtil::parseCookieHeader):
+        * platform/network/curl/CurlResourceHandleDelegate.cpp:
+        (WebCore::handleCookieHeaders):
+        (WebCore::CurlResourceHandleDelegate::curlDidReceiveResponse):
+
 2019-03-05  Zalan Bujtas  <za...@apple.com>
 
         [ContentChangeObserver] Assert on if notify content change is allowed

Modified: trunk/Source/WebCore/platform/network/curl/CookieJarCurl.cpp (242516 => 242517)


--- trunk/Source/WebCore/platform/network/curl/CookieJarCurl.cpp	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarCurl.cpp	2019-03-05 23:36:56 UTC (rev 242517)
@@ -39,7 +39,7 @@
 
 namespace WebCore {
 
-static String cookiesForSession(const NetworkStorageSession& session, const URL&, const URL& url, bool forHTTPHeader)
+static String cookiesForSession(const NetworkStorageSession& session, const URL& firstParty, const URL& url, bool forHTTPHeader)
 {
     StringBuilder cookies;
 
@@ -47,7 +47,7 @@
     auto searchHTTPOnly = (forHTTPHeader ? WTF::nullopt : Optional<bool> {false});
     auto secure = url.protocolIs("https") ? WTF::nullopt : Optional<bool> {false};
 
-    if (auto result = cookieJarDB.searchCookies(url.string(), searchHTTPOnly, secure, WTF::nullopt)) {
+    if (auto result = cookieJarDB.searchCookies(firstParty, url, searchHTTPOnly, secure, WTF::nullopt)) {
         for (auto& cookie : *result) {
             if (!cookies.isEmpty())
                 cookies.append("; ");
@@ -63,16 +63,15 @@
 {
     UNUSED_PARAM(frameID);
     UNUSED_PARAM(pageID);
-    UNUSED_PARAM(firstParty);
 
     CookieJarDB& cookieJarDB = session.cookieDatabase();
-    cookieJarDB.setCookie(url.string(), value, CookieJarDB::Source::Script);
+    cookieJarDB.setCookie(firstParty, url, value, CookieJarDB::Source::Script);
 }
 
-void CookieJarCurl::setCookiesFromHTTPResponse(const NetworkStorageSession& session, const URL& url, const String& value) const
+void CookieJarCurl::setCookiesFromHTTPResponse(const NetworkStorageSession& session, const URL& firstParty, const URL& url, const String& value) const
 {
     CookieJarDB& cookieJarDB = session.cookieDatabase();
-    cookieJarDB.setCookie(url.string(), value, CookieJarDB::Source::Network);
+    cookieJarDB.setCookie(firstParty, url, value, CookieJarDB::Source::Network);
 }
 
 std::pair<String, bool> CookieJarCurl::cookiesForDOM(const NetworkStorageSession& session, const URL& firstParty, const SameSiteInfo&, const URL& url, Optional<uint64_t> frameID, Optional<uint64_t> pageID, IncludeSecureCookies) const
@@ -98,6 +97,17 @@
     return cookieRequestHeaderFieldValue(session, headerFieldProxy.firstParty, headerFieldProxy.sameSiteInfo, headerFieldProxy.url, headerFieldProxy.frameID, headerFieldProxy.pageID, headerFieldProxy.includeSecureCookies);
 }
 
+void CookieJarCurl::setCookieAcceptPolicy(const NetworkStorageSession& session, CookieAcceptPolicy policy) const
+{
+    auto& cookieJarDB = session.cookieDatabase();
+    cookieJarDB.setAcceptPolicy(policy);
+}
+
+CookieAcceptPolicy CookieJarCurl::cookieAcceptPolicy(const NetworkStorageSession& session) const
+{
+    return session.cookieDatabase().acceptPolicy();
+}
+
 bool CookieJarCurl::cookiesEnabled(const NetworkStorageSession& session) const
 {
     return session.cookieDatabase().isEnabled();
@@ -109,7 +119,7 @@
     UNUSED_PARAM(pageID);
 
     CookieJarDB& cookieJarDB = session.cookieDatabase();
-    if (auto cookies = cookieJarDB.searchCookies(firstParty.string(), WTF::nullopt, WTF::nullopt, WTF::nullopt)) {
+    if (auto cookies = cookieJarDB.searchCookies(firstParty, firstParty, WTF::nullopt, WTF::nullopt, WTF::nullopt)) {
         rawCookies = WTFMove(*cookies);
         return true;
     }

Modified: trunk/Source/WebCore/platform/network/curl/CookieJarCurl.h (242516 => 242517)


--- trunk/Source/WebCore/platform/network/curl/CookieJarCurl.h	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarCurl.h	2019-03-05 23:36:56 UTC (rev 242517)
@@ -37,12 +37,15 @@
 struct Cookie;
 struct CookieRequestHeaderFieldProxy;
 struct SameSiteInfo;
+enum class CookieAcceptPolicy;
 
 class CookieJarCurl {
 public:
     std::pair<String, bool> cookiesForDOM(const NetworkStorageSession&, const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<uint64_t> pageID, IncludeSecureCookies) const;
     void setCookiesFromDOM(const NetworkStorageSession&, const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<uint64_t> pageID, const String&) const;
-    void setCookiesFromHTTPResponse(const NetworkStorageSession&, const URL&, const String&) const;
+    void setCookiesFromHTTPResponse(const NetworkStorageSession&, const URL& firstParty, const URL&, const String&) const;
+    void setCookieAcceptPolicy(const NetworkStorageSession&, CookieAcceptPolicy) const;
+    CookieAcceptPolicy cookieAcceptPolicy(const NetworkStorageSession&) const;
     bool cookiesEnabled(const NetworkStorageSession&) const;
     std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession&, const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<uint64_t> pageID, IncludeSecureCookies) const;
     std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession&, const CookieRequestHeaderFieldProxy&) const;

Modified: trunk/Source/WebCore/platform/network/curl/CookieJarDB.cpp (242516 => 242517)


--- trunk/Source/WebCore/platform/network/curl/CookieJarDB.cpp	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarDB.cpp	2019-03-05 23:36:56 UTC (rev 242517)
@@ -27,6 +27,7 @@
 
 #include "CookieUtil.h"
 #include "Logging.h"
+#include "RegistrableDomain.h"
 #include "SQLiteFileSystem.h"
 #include <wtf/FileSystem.h>
 #include <wtf/MonotonicTime.h>
@@ -33,10 +34,6 @@
 #include <wtf/URL.h>
 #include <wtf/text/StringConcatenateNumbers.h>
 
-#if ENABLE(PUBLIC_SUFFIX_LIST)
-#include "PublicSuffix.h"
-#endif
-
 namespace WebCore {
 
 #define CORRUPT_MARKER_SUFFIX "-corrupted"
@@ -61,6 +58,8 @@
     "CREATE INDEX IF NOT EXISTS domain_index ON Cookie(domain);"
 #define CREATE_PATH_INDEX_SQL \
     "CREATE INDEX IF NOT EXISTS path_index ON Cookie(path);"
+#define CHECK_EXISTS_COOKIE_SQL \
+    "SELECT domain FROM Cookie WHERE ((domain = ?) OR (domain GLOB ?));"
 #define CHECK_EXISTS_HTTPONLY_COOKIE_SQL \
     "SELECT name FROM Cookie WHERE (name = ?) AND (domain = ?) AND (path = ?) AND (httponly = 1);"
 #define SET_COOKIE_SQL \
@@ -82,11 +81,6 @@
 static constexpr int schemaVersion = 1;
 
 
-void CookieJarDB::setEnabled(bool enable)
-{
-    m_isEnabled = enable;
-}
-
 CookieJarDB::CookieJarDB(const String& databasePath)
     : m_databasePath(databasePath)
 {
@@ -162,6 +156,7 @@
 
     // create prepared statements
     createPrepareStatement(SET_COOKIE_SQL);
+    createPrepareStatement(CHECK_EXISTS_COOKIE_SQL);
     createPrepareStatement(CHECK_EXISTS_HTTPONLY_COOKIE_SQL);
     createPrepareStatement(DELETE_COOKIE_BY_NAME_DOMAIN_PATH_SQL);
     createPrepareStatement(DELETE_COOKIE_BY_NAME_DOMAIN_SQL);
@@ -309,24 +304,72 @@
     if (m_databasePath.isEmpty())
         return false;
 
-    return m_isEnabled;
+    return (m_acceptPolicy == CookieAcceptPolicy::Always || m_acceptPolicy == CookieAcceptPolicy::OnlyFromMainDocumentDomain || m_acceptPolicy == CookieAcceptPolicy::ExclusivelyFromMainDocumentDomain);
 }
 
-Optional<Vector<Cookie>> CookieJarDB::searchCookies(const String& requestUrl, const Optional<bool>& httpOnly, const Optional<bool>& secure, const Optional<bool>& session)
+bool CookieJarDB::checkCookieAcceptPolicy(const URL& firstParty, const URL& url)
 {
+    if (m_acceptPolicy == CookieAcceptPolicy::Always)
+        return true;
+
+    // See https://bugs.webkit.org/show_bug.cgi?id=193458#c0
+    if (m_acceptPolicy != CookieAcceptPolicy::OnlyFromMainDocumentDomain && m_acceptPolicy != CookieAcceptPolicy::ExclusivelyFromMainDocumentDomain)
+        return false;
+
+    if (firstParty.host() == url.host())
+        return true;
+
+    if (RegistrableDomain(firstParty).matches(url))
+        return true;
+
+    // third-party resources can read or write cookies if they have pre-existing cookies.
+    if (m_acceptPolicy == CookieAcceptPolicy::OnlyFromMainDocumentDomain && hasCookies(url))
+        return true;
+
+    return false;
+}
+
+bool CookieJarDB::hasCookies(const URL& url)
+{
+    String host = url.host().convertToASCIILowercase();
+    if (host.isEmpty())
+        return false;
+
+    if (isPublicSuffix(host))
+        return false;
+
+    RegistrableDomain registrableDomain { url };
+    auto& statement = preparedStatement(CHECK_EXISTS_COOKIE_SQL);
+
+    if (CookieUtil::isIPAddress(host) || !host.contains('.') || registrableDomain.isEmpty()) {
+        statement.bindText(1, host);
+        statement.bindNull(2);
+    } else {
+        statement.bindText(1, registrableDomain.string());
+        statement.bindText(2, String("*.") + registrableDomain.string());
+    }
+
+    return statement.step() == SQLITE_ROW;
+}
+
+Optional<Vector<Cookie>> CookieJarDB::searchCookies(const URL& firstParty, const URL& requestUrl, const Optional<bool>& httpOnly, const Optional<bool>& secure, const Optional<bool>& session)
+{
     if (!isEnabled() || !m_database.isOpen())
         return WTF::nullopt;
 
-    URL requestUrlObj({ }, requestUrl);
-    String requestHost(requestUrlObj.host().toString().convertToASCIILowercase());
-    String requestPath(requestUrlObj.path().convertToASCIILowercase());
-
+    String requestHost = requestUrl.host().convertToASCIILowercase();
     if (requestHost.isEmpty())
         return WTF::nullopt;
 
+    if (!checkCookieAcceptPolicy(firstParty, requestUrl))
+        return WTF::nullopt;
+
+    String requestPath = requestUrl.path();
     if (requestPath.isEmpty())
         requestPath = "/";
 
+    RegistrableDomain registrableDomain { requestUrl };
+
     const String sql =
         "SELECT name, value, domain, path, expires, httponly, secure, session FROM Cookie WHERE "\
         "(NOT ((session = 0) AND (datetime(expires, 'unixepoch') < datetime('now')))) "\
@@ -346,27 +389,11 @@
     pstmt->bindInt(3, session ? *session : -1);
     pstmt->bindText(4, requestHost);
 
-    if (CookieUtil::isIPAddress(requestHost) || !requestHost.contains('.'))
+    if (CookieUtil::isIPAddress(requestHost) || !requestHost.contains('.') || registrableDomain.isEmpty())
         pstmt->bindNull(5);
-    else {
-#if ENABLE(PUBLIC_SUFFIX_LIST)
-        String topPrivateDomain = topPrivatelyControlledDomain(requestHost);
-        if (!topPrivateDomain.isEmpty())
-            pstmt->bindText(5, String("*.") + topPrivateDomain);
-        else
-            pstmt->bindNull(5);
-#else
-        // Fallback to glob for cookies under the second level domain e.g. *.domain.com
-        // This will return too many cookies under multilevel tlds such as *.co.uk, but they will get filtered out later.
-        size_t topLevelSeparator = requestHost.reverseFind('.');
-        size_t secondLevelSeparator = requestHost.reverseFind('.', topLevelSeparator-1);
-        String localDomain = secondLevelSeparator == notFound ? requestHost : requestHost.substring(secondLevelSeparator+1);
+    else
+        pstmt->bindText(5, String("*.") + registrableDomain.string());
 
-        ASSERT(!localDomain.isEmpty());
-        pstmt->bindText(5, String("*.") + localDomain);
-#endif
-    }
-
     if (!pstmt)
         return WTF::nullopt;
 
@@ -380,7 +407,7 @@
         String cookieName = pstmt->getColumnText(0);
         String cookieValue = pstmt->getColumnText(1);
         String cookieDomain = pstmt->getColumnText(2).convertToASCIILowercase();
-        String cookiePath = pstmt->getColumnText(3).convertToASCIILowercase();
+        String cookiePath = pstmt->getColumnText(3);
         double cookieExpires = (double)pstmt->getColumnInt64(4) * 1000;
         bool cookieHttpOnly = (pstmt->getColumnInt(5) == 1);
         bool cookieSecure = (pstmt->getColumnInt(6) == 1);
@@ -424,20 +451,21 @@
     return statement.step() == SQLITE_ROW;
 }
 
-bool CookieJarDB::canAcceptCookie(const Cookie& cookie, const String& host, CookieJarDB::Source source)
+bool CookieJarDB::canAcceptCookie(const Cookie& cookie, const URL& firstParty, const URL& url, CookieJarDB::Source source)
 {
-#if ENABLE(PUBLIC_SUFFIX_LIST)
     if (isPublicSuffix(cookie.domain))
         return false;
-#endif
 
     bool fromJavaScript = source == CookieJarDB::Source::Script;
     if (fromJavaScript && (cookie.httpOnly || hasHttpOnlyCookie(cookie.name, cookie.domain, cookie.path)))
         return false;
 
-    if (!CookieUtil::domainMatch(cookie.domain, host))
+    if (!CookieUtil::domainMatch(cookie.domain, url.host().convertToASCIILowercase()))
         return false;
 
+    if (!checkCookieAcceptPolicy(firstParty, url))
+        return false;
+
     return true;
 }
 
@@ -461,7 +489,7 @@
     return checkSQLiteReturnCode(statement.step());
 }
 
-bool CookieJarDB::setCookie(const String& url, const String& body, CookieJarDB::Source source)
+bool CookieJarDB::setCookie(const URL& firstParty, const URL& url, const String& body, CookieJarDB::Source source)
 {
     if (!isEnabled() || !m_database.isOpen())
         return false;
@@ -469,21 +497,17 @@
     if (url.isEmpty() || body.isEmpty())
         return false;
 
-    URL urlObj({ }, url);
-    String host(urlObj.host().toString());
-    String path(urlObj.path());
-
     auto cookie = CookieUtil::parseCookieHeader(body);
     if (!cookie)
         return false;
 
     if (cookie->domain.isEmpty())
-        cookie->domain = String(host);
+        cookie->domain = url.host().convertToASCIILowercase();
 
     if (cookie->path.isEmpty())
-        cookie->path = CookieUtil::defaultPathForURL(urlObj);
+        cookie->path = CookieUtil::defaultPathForURL(url);
 
-    if (!canAcceptCookie(*cookie, host, source))
+    if (!canAcceptCookie(*cookie, firstParty, url, source))
         return false;
 
     return setCookie(*cookie);

Modified: trunk/Source/WebCore/platform/network/curl/CookieJarDB.h (242516 => 242517)


--- trunk/Source/WebCore/platform/network/curl/CookieJarDB.h	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarDB.h	2019-03-05 23:36:56 UTC (rev 242517)
@@ -36,6 +36,13 @@
 
 namespace WebCore {
 
+enum class CookieAcceptPolicy {
+    Always,
+    Never,
+    OnlyFromMainDocumentDomain,
+    ExclusivelyFromMainDocumentDomain
+};
+
 class CookieJarDB {
     WTF_MAKE_NONCOPYABLE(CookieJarDB);
 
@@ -44,12 +51,15 @@
         Network,
         Script
     };
+
     void open();
     bool isEnabled() const;
-    void setEnabled(bool);
 
-    Optional<Vector<Cookie>> searchCookies(const String& requestUrl, const Optional<bool>& httpOnly, const Optional<bool>& secure, const Optional<bool>& session);
-    bool setCookie(const String& url, const String& cookie, Source);
+    void setAcceptPolicy(CookieAcceptPolicy policy) { m_acceptPolicy = policy; }
+    CookieAcceptPolicy acceptPolicy() const { return m_acceptPolicy; }
+
+    Optional<Vector<Cookie>> searchCookies(const URL& firstParty, const URL& requestUrl, const Optional<bool>& httpOnly, const Optional<bool>& secure, const Optional<bool>& session);
+    bool setCookie(const URL& firstParty, const URL&, const String& cookie, Source);
     bool setCookie(const Cookie&);
 
     bool deleteCookie(const String& url, const String& name);
@@ -60,8 +70,7 @@
     WEBCORE_EXPORT ~CookieJarDB();
 
 private:
-
-    bool m_isEnabled { true };
+    CookieAcceptPolicy m_acceptPolicy { CookieAcceptPolicy::Always };
     String m_databasePath;
 
     bool m_detectedDatabaseCorruption { false };
@@ -88,7 +97,9 @@
 
     bool deleteCookieInternal(const String& name, const String& domain, const String& path);
     bool hasHttpOnlyCookie(const String& name, const String& domain, const String& path);
-    bool canAcceptCookie(const Cookie&, const String& host, CookieJarDB::Source);
+    bool canAcceptCookie(const Cookie&, const URL& firstParty, const URL&, CookieJarDB::Source);
+    bool checkCookieAcceptPolicy(const URL& firstParty, const URL&);
+    bool hasCookies(const URL&);
 
     SQLiteDatabase m_database;
     HashMap<String, std::unique_ptr<SQLiteStatement>> m_statements;

Modified: trunk/Source/WebCore/platform/network/curl/CookieUtil.cpp (242516 => 242517)


--- trunk/Source/WebCore/platform/network/curl/CookieUtil.cpp	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebCore/platform/network/curl/CookieUtil.cpp	2019-03-05 23:36:56 UTC (rev 242517)
@@ -113,7 +113,7 @@
         if (!isIPAddress(attributeValue) && !attributeValue.startsWith('.') && attributeValue.find('.') != notFound)
             attributeValue = "." + attributeValue;
 
-        result.domain = attributeValue;
+        result.domain = attributeValue.convertToASCIILowercase();
 
     } else if (equalIgnoringASCIICase(attributeName, "max-age")) {
         bool ok;
@@ -150,7 +150,7 @@
 
     String cookieName;
     String cookieValue;
-    size_t assignmentPosition = cookieLine.find('=');
+    size_t assignmentPosition = cookiePair.find('=');
 
     // RFC6265 says to ignore cookies pairs with empty names or no assignment character
     // but browsers seem to treat this type of cookie string as the cookie value

Modified: trunk/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.cpp (242516 => 242517)


--- trunk/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.cpp	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.cpp	2019-03-05 23:36:56 UTC (rev 242517)
@@ -85,7 +85,7 @@
     client()->didSendData(&m_handle, bytesSent, totalBytesToBeSent);
 }
 
-static void handleCookieHeaders(ResourceHandleInternal* d, const CurlResponse& response)
+static void handleCookieHeaders(ResourceHandleInternal* d, const ResourceRequest& request, const CurlResponse& response)
 {
     static const auto setCookieHeader = "set-cookie: ";
 
@@ -94,7 +94,7 @@
     for (const auto& header : response.headers) {
         if (header.startsWithIgnoringASCIICase(setCookieHeader)) {
             const auto contents = header.right(header.length() - strlen(setCookieHeader));
-            cookieJar.setCookiesFromHTTPResponse(storageSession, response.url, contents);
+            cookieJar.setCookiesFromHTTPResponse(storageSession, request.firstPartyForCookies(), response.url, contents);
         }
     }
 }
@@ -112,7 +112,7 @@
     m_response.setCertificateInfo(request.certificateInfo().isolatedCopy());
     m_response.setDeprecatedNetworkLoadMetrics(request.networkLoadMetrics().isolatedCopy());
 
-    handleCookieHeaders(d(), receivedResponse);
+    handleCookieHeaders(d(), request.resourceRequest(), receivedResponse);
 
     if (m_response.shouldRedirect()) {
         m_handle.willSendRequest();

Modified: trunk/Source/WebKit/ChangeLog (242516 => 242517)


--- trunk/Source/WebKit/ChangeLog	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebKit/ChangeLog	2019-03-05 23:36:56 UTC (rev 242517)
@@ -1,3 +1,18 @@
+2019-03-05  Takashi Komori  <takashi.kom...@sony.com>
+
+        [Curl] Implement Cookie Accept Policy.
+        https://bugs.webkit.org/show_bug.cgi?id=191645
+
+        Reviewed by Fujii Hironori.
+
+        * NetworkProcess/Cookies/curl/WebCookieManagerCurl.cpp:
+        (WebKit::WebCookieManager::platformSetHTTPCookieAcceptPolicy):
+        (WebKit::WebCookieManager::platformGetHTTPCookieAcceptPolicy):
+        * NetworkProcess/curl/NetworkDataTaskCurl.cpp:
+        (WebKit::NetworkDataTaskCurl::curlDidReceiveResponse):
+        (WebKit::NetworkDataTaskCurl::handleCookieHeaders):
+        * NetworkProcess/curl/NetworkDataTaskCurl.h:
+
 2019-03-05  Youenn Fablet  <you...@apple.com>
 
         Introduce ServiceWorkerFetchTask

Modified: trunk/Source/WebKit/NetworkProcess/Cookies/curl/WebCookieManagerCurl.cpp (242516 => 242517)


--- trunk/Source/WebKit/NetworkProcess/Cookies/curl/WebCookieManagerCurl.cpp	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebKit/NetworkProcess/Cookies/curl/WebCookieManagerCurl.cpp	2019-03-05 23:36:56 UTC (rev 242517)
@@ -26,16 +26,51 @@
 #include "config.h"
 #include "WebCookieManager.h"
 
+#include "NetworkProcess.h"
+#include <WebCore/NetworkStorageSession.h>
+
 namespace WebKit {
 
 using namespace WebCore;
 
-void WebCookieManager::platformSetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy)
+void WebCookieManager::platformSetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy)
 {
+    CookieAcceptPolicy curlPolicy = CookieAcceptPolicy::OnlyFromMainDocumentDomain;
+    switch (policy) {
+    case HTTPCookieAcceptPolicyAlways:
+        curlPolicy = CookieAcceptPolicy::Always;
+        break;
+    case HTTPCookieAcceptPolicyNever:
+        curlPolicy = CookieAcceptPolicy::Never;
+        break;
+    case HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:
+        curlPolicy = CookieAcceptPolicy::OnlyFromMainDocumentDomain;
+        break;
+    case HTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain:
+        curlPolicy = CookieAcceptPolicy::ExclusivelyFromMainDocumentDomain;
+        break;
+    }
+
+    m_process.forEachNetworkStorageSession([curlPolicy] (const auto& networkStorageSession) {
+        networkStorageSession.cookieStorage().setCookieAcceptPolicy(networkStorageSession, curlPolicy);
+    });
 }
 
 HTTPCookieAcceptPolicy WebCookieManager::platformGetHTTPCookieAcceptPolicy()
 {
+    const auto& networkStorageSession = m_process.defaultStorageSession();
+    switch (networkStorageSession.cookieStorage().cookieAcceptPolicy(networkStorageSession)) {
+    case CookieAcceptPolicy::Always:
+        return HTTPCookieAcceptPolicyAlways;
+    case CookieAcceptPolicy::Never:
+        return HTTPCookieAcceptPolicyNever;
+    case CookieAcceptPolicy::OnlyFromMainDocumentDomain:
+        return HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
+    case CookieAcceptPolicy::ExclusivelyFromMainDocumentDomain:
+        return HTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain;
+    }
+
+    ASSERT_NOT_REACHED();
     return HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
 }
 

Modified: trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp (242516 => 242517)


--- trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.cpp	2019-03-05 23:36:56 UTC (rev 242517)
@@ -149,7 +149,7 @@
     m_response = ResourceResponse(receivedResponse);
     m_response.setDeprecatedNetworkLoadMetrics(request.networkLoadMetrics().isolatedCopy());
 
-    handleCookieHeaders(receivedResponse);
+    handleCookieHeaders(request.resourceRequest(), receivedResponse);
 
     if (m_response.shouldRedirect()) {
         willPerformHTTPRedirection();
@@ -427,7 +427,7 @@
         request.addHTTPHeaderField(HTTPHeaderName::Cookie, cookieHeaderField);
 }
 
-void NetworkDataTaskCurl::handleCookieHeaders(const CurlResponse& response)
+void NetworkDataTaskCurl::handleCookieHeaders(const WebCore::ResourceRequest& request, const CurlResponse& response)
 {
     static const auto setCookieHeader = "set-cookie: ";
 
@@ -436,7 +436,7 @@
     for (auto header : response.headers) {
         if (header.startsWithIgnoringASCIICase(setCookieHeader)) {
             String setCookieString = header.right(header.length() - strlen(setCookieHeader));
-            cookieJar.setCookiesFromHTTPResponse(storageSession, response.url, setCookieString);
+            cookieJar.setCookiesFromHTTPResponse(storageSession, request.firstPartyForCookies(), response.url, setCookieString);
         }
     }
 }

Modified: trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h (242516 => 242517)


--- trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h	2019-03-05 23:36:56 UTC (rev 242517)
@@ -79,7 +79,7 @@
     void restartWithCredential(const WebCore::ProtectionSpace&, const WebCore::Credential&);
 
     void appendCookieHeader(WebCore::ResourceRequest&);
-    void handleCookieHeaders(const WebCore::CurlResponse&);
+    void handleCookieHeaders(const WebCore::ResourceRequest&, const WebCore::CurlResponse&);
 
     State m_state { State::Suspended };
 

Modified: trunk/Tools/ChangeLog (242516 => 242517)


--- trunk/Tools/ChangeLog	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Tools/ChangeLog	2019-03-05 23:36:56 UTC (rev 242517)
@@ -1,3 +1,13 @@
+2019-03-05  Takashi Komori  <takashi.kom...@sony.com>
+
+        [Curl] Implement Cookie Accept Policy.
+        https://bugs.webkit.org/show_bug.cgi?id=191645
+
+        Reviewed by Fujii Hironori.
+
+        * TestWebKitAPI/Tests/WebCore/curl/Cookies.cpp:
+        (TestWebKitAPI::Curl::TEST_F):
+
 2019-03-05  Youenn Fablet  <you...@apple.com>
 
         Rename requestCacheStorageSpace to requestStorageSpace

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/curl/Cookies.cpp (242516 => 242517)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/curl/Cookies.cpp	2019-03-05 23:35:02 UTC (rev 242516)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/curl/Cookies.cpp	2019-03-05 23:36:56 UTC (rev 242517)
@@ -46,7 +46,7 @@
 
         m_cookieJar = std::make_unique<WebCore::CookieJarDB>(FileSystem::pathByAppendingComponent(m_cookieDirectory, "cookiedb.sql"));
         m_cookieJar->open();
-        m_cookieJar->setEnabled(true);
+        m_cookieJar->setAcceptPolicy(CookieAcceptPolicy::Always);
     }
 
     void TearDown() final
@@ -64,26 +64,30 @@
 
 TEST_F(CurlCookies, RejectTailmatchFailureDomain)
 {
+    URL url(URL(), "http://example.com");
+
     // success: domain match
-    EXPECT_TRUE(m_cookieJar->setCookie("http://example.com", "foo=bar; Domain=example.com", CookieJarDB::Source::Network));
+    EXPECT_TRUE(m_cookieJar->setCookie(url, url, "foo=bar; Domain=example.com", CookieJarDB::Source::Network));
     // success: wildcard of domains
-    EXPECT_TRUE(m_cookieJar->setCookie("http://example.com", "foo=bar; Domain=.example.com", CookieJarDB::Source::Network));
+    EXPECT_TRUE(m_cookieJar->setCookie(url, url, "foo=bar; Domain=.example.com", CookieJarDB::Source::Network));
     // failure: specific sub domain
-    EXPECT_FALSE(m_cookieJar->setCookie("http://example.com", "foo=bar; Domain=www.example.com", CookieJarDB::Source::Network));
+    EXPECT_FALSE(m_cookieJar->setCookie(url, url, "foo=bar; Domain=www.example.com", CookieJarDB::Source::Network));
     // failure: different domain
-    EXPECT_FALSE(m_cookieJar->setCookie("http://example.com", "foo=bar; Domain=sample.com", CookieJarDB::Source::Network));
+    EXPECT_FALSE(m_cookieJar->setCookie(url, url, "foo=bar; Domain=sample.com", CookieJarDB::Source::Network));
 }
 
 TEST_F(CurlCookies, TestHttpOnlyCase)
 {
+    URL url(URL(), "http://example.com");
+
     // success: from network
-    EXPECT_TRUE(m_cookieJar->setCookie("http://example.com", "foo=bar; HttpOnly", CookieJarDB::Source::Network));
+    EXPECT_TRUE(m_cookieJar->setCookie(url, url, "foo=bar; HttpOnly", CookieJarDB::Source::Network));
     // success: wildcard of domains
-    EXPECT_TRUE(m_cookieJar->setCookie("http://example.com", "bingo=bongo;", CookieJarDB::Source::Script));
+    EXPECT_TRUE(m_cookieJar->setCookie(url, url, "bingo=bongo;", CookieJarDB::Source::Script));
     // failure: foo is already stored as HttpOnly
-    EXPECT_FALSE(m_cookieJar->setCookie("http://example.com", "foo=bar;", CookieJarDB::Source::Script));
+    EXPECT_FALSE(m_cookieJar->setCookie(url, url, "foo=bar;", CookieJarDB::Source::Script));
     // failure: inconsistent. Source is Script, but attribute says HttpOnly
-    EXPECT_FALSE(m_cookieJar->setCookie("http://example.com", "foo=bar; HttpOnly", CookieJarDB::Source::Script));
+    EXPECT_FALSE(m_cookieJar->setCookie(url, url, "foo=bar; HttpOnly", CookieJarDB::Source::Script));
 }
 
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to