Title: [230875] trunk/Source
Revision
230875
Author
bfulg...@apple.com
Date
2018-04-20 18:51:37 -0700 (Fri, 20 Apr 2018)

Log Message

Limit cookie header access to Network process
https://bugs.webkit.org/show_bug.cgi?id=184764
<rdar://problem/36785285>

Reviewed by Youenn Fablet.

Revise the handling of cookie request headers so that we don't interact with them in the
WebContent process. They are only needed for interaction with the server and the network
process, so we should limit their scope to just the Network process.

Instead, we should handle a token that represents the cookie headers in the WebContent
process, which can be converted to the relevant cookie data in the network process when
needed.

Source/WebCore:

* Modules/websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::didOpenSocketStream):
* Modules/websockets/WebSocketHandshake.cpp:
(WebCore::WebSocketHandshake::clientHandshakeMessage const):
(WebCore::WebSocketHandshake::clientHandshakeRequest const):
(WebCore::WebSocketHandshake::clientHandshakeCookieRequestHeaderFieldProxy const):
(WebCore::WebSocketHandshake::clientHandshakeMessage): Deleted.
(WebCore::WebSocketHandshake::clientHandshakeRequest): Deleted.
* Modules/websockets/WebSocketHandshake.h:
* WebCore.xcodeproj/project.pbxproj:
* loader/CookieJar.cpp:
(WebCore::cookieRequestHeaderFieldProxy):
* loader/CookieJar.h:
* platform/network/CookieRequestHeaderFieldProxy.h: Added.
(WebCore::CookieRequestHeaderFieldProxy::CookieRequestHeaderFieldProxy):
(WebCore::CookieRequestHeaderFieldProxy::isolatedCopy const):
(WebCore::CookieRequestHeaderFieldProxy::encode const):
(WebCore::CookieRequestHeaderFieldProxy::decode):
* platform/network/PlatformCookieJar.h:
* platform/network/SocketStreamHandle.cpp:
(WebCore::SocketStreamHandle::sendHandshake):
* platform/network/SocketStreamHandle.h:
* platform/network/SocketStreamHandleImpl.cpp:
(WebCore::SocketStreamHandleImpl::platformSendHandshake):
* platform/network/cf/SocketStreamHandleImpl.h:
* platform/network/curl/CookieJarCurl.cpp:
(WebCore::cookieRequestHeaderFieldValue):
* platform/network/curl/CookieJarCurl.h:
* platform/network/curl/SocketStreamHandleImpl.h:
* platform/network/mac/CookieJarMac.mm:
(WebCore::cookieRequestHeaderFieldValue):
* platform/network/soup/CookieJarSoup.cpp:
(WebCore::cookieRequestHeaderFieldValue):
* platform/network/soup/SocketStreamHandleImpl.h:

Source/WebKit:

* NetworkProcess/NetworkSocketStream.cpp:
(WebKit::NetworkSocketStream::sendHandshake):
* NetworkProcess/NetworkSocketStream.h:
* NetworkProcess/NetworkSocketStream.messages.in:
* WebProcess/Network/WebSocketStream.cpp:
(WebKit::WebSocketStream::networkProcessCrashed):
(WebKit::WebSocketStream::platformSendHandshake):
(WebKit::WebSocketStream::didSendHandshake):
* WebProcess/Network/WebSocketStream.h:
* WebProcess/Network/WebSocketStream.messages.in:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (230874 => 230875)


--- trunk/Source/WebCore/ChangeLog	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/ChangeLog	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,3 +1,54 @@
+2018-04-20  Brent Fulgham  <bfulg...@apple.com>
+
+        Limit cookie header access to Network process
+        https://bugs.webkit.org/show_bug.cgi?id=184764
+        <rdar://problem/36785285>
+
+        Reviewed by Youenn Fablet.
+
+        Revise the handling of cookie request headers so that we don't interact with them in the
+        WebContent process. They are only needed for interaction with the server and the network
+        process, so we should limit their scope to just the Network process.
+
+        Instead, we should handle a token that represents the cookie headers in the WebContent
+        process, which can be converted to the relevant cookie data in the network process when
+        needed.
+
+        * Modules/websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::didOpenSocketStream):
+        * Modules/websockets/WebSocketHandshake.cpp:
+        (WebCore::WebSocketHandshake::clientHandshakeMessage const):
+        (WebCore::WebSocketHandshake::clientHandshakeRequest const):
+        (WebCore::WebSocketHandshake::clientHandshakeCookieRequestHeaderFieldProxy const):
+        (WebCore::WebSocketHandshake::clientHandshakeMessage): Deleted.
+        (WebCore::WebSocketHandshake::clientHandshakeRequest): Deleted.
+        * Modules/websockets/WebSocketHandshake.h:
+        * WebCore.xcodeproj/project.pbxproj:
+        * loader/CookieJar.cpp:
+        (WebCore::cookieRequestHeaderFieldProxy):
+        * loader/CookieJar.h:
+        * platform/network/CookieRequestHeaderFieldProxy.h: Added.
+        (WebCore::CookieRequestHeaderFieldProxy::CookieRequestHeaderFieldProxy):
+        (WebCore::CookieRequestHeaderFieldProxy::isolatedCopy const):
+        (WebCore::CookieRequestHeaderFieldProxy::encode const):
+        (WebCore::CookieRequestHeaderFieldProxy::decode):
+        * platform/network/PlatformCookieJar.h:
+        * platform/network/SocketStreamHandle.cpp:
+        (WebCore::SocketStreamHandle::sendHandshake):
+        * platform/network/SocketStreamHandle.h:
+        * platform/network/SocketStreamHandleImpl.cpp:
+        (WebCore::SocketStreamHandleImpl::platformSendHandshake):
+        * platform/network/cf/SocketStreamHandleImpl.h:
+        * platform/network/curl/CookieJarCurl.cpp:
+        (WebCore::cookieRequestHeaderFieldValue):
+        * platform/network/curl/CookieJarCurl.h:
+        * platform/network/curl/SocketStreamHandleImpl.h:
+        * platform/network/mac/CookieJarMac.mm:
+        (WebCore::cookieRequestHeaderFieldValue):
+        * platform/network/soup/CookieJarSoup.cpp:
+        (WebCore::cookieRequestHeaderFieldValue):
+        * platform/network/soup/SocketStreamHandleImpl.h:
+
 2018-04-20  Daniel Bates  <daba...@apple.com>
 
         Hide Strong Password label when text field is too narrow

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp (230874 => 230875)


--- trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2011, 2012 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
@@ -270,12 +271,16 @@
     ASSERT(&handle == m_handle);
     if (!m_document)
         return;
-    if (m_identifier)
+    if (m_identifier && UNLIKELY(InspectorInstrumentation::hasFrontends()))
         InspectorInstrumentation::willSendWebSocketHandshakeRequest(m_document, m_identifier, m_handshake->clientHandshakeRequest());
-    CString handshakeMessage = m_handshake->clientHandshakeMessage();
-    handle.sendData(handshakeMessage.data(), handshakeMessage.length(), [this, protectedThis = makeRef(*this)] (bool success) {
+    auto handshakeMessage = m_handshake->clientHandshakeMessage();
+    auto cookieRequestHeaderFieldProxy = m_handshake->clientHandshakeCookieRequestHeaderFieldProxy();
+    handle.sendHandshake(WTFMove(handshakeMessage), WTFMove(cookieRequestHeaderFieldProxy), [this, protectedThis = makeRef(*this)] (bool success, bool didAccessSecureCookies) {
         if (!success)
             fail("Failed to send WebSocket handshake.");
+
+        if (didAccessSecureCookies && m_document)
+            m_document->setSecureCookiesAccessed();
     });
 }
 

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp (230874 => 230875)


--- trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011 Google Inc.  All rights reserved.
  * Copyright (C) Research In Motion Limited 2011. 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,6 +39,7 @@
 #include "HTTPHeaderMap.h"
 #include "HTTPHeaderNames.h"
 #include "HTTPParsers.h"
+#include "InspectorInstrumentation.h"
 #include "Logging.h"
 #include "ResourceRequest.h"
 #include "ScriptExecutionContext.h"
@@ -177,7 +179,7 @@
     return builder.toString();
 }
 
-CString WebSocketHandshake::clientHandshakeMessage()
+CString WebSocketHandshake::clientHandshakeMessage() const
 {
     // Keep the following consistent with clientHandshakeRequest().
     StringBuilder builder;
@@ -194,12 +196,8 @@
     if (!m_clientProtocol.isEmpty())
         fields.append("Sec-WebSocket-Protocol: " + m_clientProtocol);
 
-    URL url = ""
-    if (m_allowCookies && m_document) {
-        String cookie = cookieRequestHeaderFieldValue(*m_document, url);
-        if (!cookie.isEmpty())
-            fields.append("Cookie: " + cookie);
-    }
+    // Note: Cookies are not retrieved in the WebContent process. Instead, a proxy object is
+    // added in the handshake, and is exchanged for actual cookies in the Network process.
 
     // Add no-cache headers to avoid compatibility issue.
     // There are some proxies that rewrite "Connection: upgrade"
@@ -231,7 +229,7 @@
     return builder.toString().utf8();
 }
 
-ResourceRequest WebSocketHandshake::clientHandshakeRequest()
+ResourceRequest WebSocketHandshake::clientHandshakeRequest() const
 {
     // Keep the following consistent with clientHandshakeMessage().
     ResourceRequest request(m_url);
@@ -245,6 +243,7 @@
 
     URL url = ""
     if (m_allowCookies && m_document) {
+        RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(InspectorInstrumentation::hasFrontends());
         String cookie = cookieRequestHeaderFieldValue(*m_document, url);
         if (!cookie.isEmpty())
             request.setHTTPHeaderField(HTTPHeaderName::Cookie, cookie);
@@ -265,6 +264,13 @@
     return request;
 }
 
+std::optional<CookieRequestHeaderFieldProxy> WebSocketHandshake::clientHandshakeCookieRequestHeaderFieldProxy() const
+{
+    if (!m_document || !m_allowCookies)
+        return std::nullopt;
+    return cookieRequestHeaderFieldProxy(*m_document, httpURLForAuthenticationAndCookies());
+}
+
 void WebSocketHandshake::reset()
 {
     m_mode = Incomplete;

Modified: trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.h (230874 => 230875)


--- trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketHandshake.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -30,6 +30,7 @@
 
 #pragma once
 
+#include "CookieRequestHeaderFieldProxy.h"
 #include "URL.h"
 #include "ResourceResponse.h"
 #include "WebSocketExtensionDispatcher.h"
@@ -63,8 +64,9 @@
     String clientOrigin() const;
     String clientLocation() const;
 
-    CString clientHandshakeMessage();
-    ResourceRequest clientHandshakeRequest();
+    CString clientHandshakeMessage() const;
+    ResourceRequest clientHandshakeRequest() const;
+    std::optional<CookieRequestHeaderFieldProxy> clientHandshakeCookieRequestHeaderFieldProxy() const;
 
     void reset();
     void clearDocument();

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (230874 => 230875)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-04-21 01:51:37 UTC (rev 230875)
@@ -2057,6 +2057,7 @@
 		7A54858014E02D51006AE05A /* InspectorHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A54857E14E02D51006AE05A /* InspectorHistory.h */; };
 		7A54881714E432A1006AE05A /* DOMPatchSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A54881514E432A1006AE05A /* DOMPatchSupport.h */; };
 		7A5515F5191830A3009687D2 /* YouTubePluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A5515F3191830A3009687D2 /* YouTubePluginReplacement.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		7A5699702086C619000E0433 /* CookieRequestHeaderFieldProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A56996E2086C618000E0433 /* CookieRequestHeaderFieldProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7A674BDC0F9EBF4E006CF099 /* PageGroupLoadDeferrer.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A674BDA0F9EBF4E006CF099 /* PageGroupLoadDeferrer.h */; };
 		7A929CA71C598AA9004DF226 /* ResourceLoadStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A929CA21C598378004DF226 /* ResourceLoadStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7A93868518DCC14500B8263D /* VTTScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A93868218DCC14500B8263D /* VTTScanner.cpp */; };
@@ -9230,6 +9231,7 @@
 		7A54881614E432A1006AE05A /* DOMPatchSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMPatchSupport.cpp; sourceTree = "<group>"; };
 		7A5515F3191830A3009687D2 /* YouTubePluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YouTubePluginReplacement.h; sourceTree = "<group>"; };
 		7A5515F4191830A3009687D2 /* YouTubePluginReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YouTubePluginReplacement.cpp; sourceTree = "<group>"; };
+		7A56996E2086C618000E0433 /* CookieRequestHeaderFieldProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CookieRequestHeaderFieldProxy.h; sourceTree = "<group>"; };
 		7A674BD90F9EBF4E006CF099 /* PageGroupLoadDeferrer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageGroupLoadDeferrer.cpp; sourceTree = "<group>"; };
 		7A674BDA0F9EBF4E006CF099 /* PageGroupLoadDeferrer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageGroupLoadDeferrer.h; sourceTree = "<group>"; };
 		7A7256B915EB9F5B007323A7 /* InspectorOverlayPage.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = InspectorOverlayPage.html; sourceTree = "<group>"; };
@@ -18794,6 +18796,7 @@
 				2EB4BCD1121F03E300EC4885 /* BlobResourceHandle.h */,
 				E43AF8E41AC5B7DD00CA717E /* CacheValidation.cpp */,
 				E43AF8E51AC5B7DD00CA717E /* CacheValidation.h */,
+				7A56996E2086C618000E0433 /* CookieRequestHeaderFieldProxy.h */,
 				E13F01EA1270E10D00DFBA71 /* CookieStorage.h */,
 				514C76590CE923A1007EF3CD /* Credential.h */,
 				514C76580CE923A1007EF3CD /* CredentialBase.cpp */,
@@ -27153,6 +27156,7 @@
 				FD31602912B0267600C1A359 /* ConvolverNode.h in Headers */,
 				D8B6152F1032495100C8554A /* Cookie.h in Headers */,
 				E1424C94164B52C800F32D40 /* CookieJar.h in Headers */,
+				7A5699702086C619000E0433 /* CookieRequestHeaderFieldProxy.h in Headers */,
 				339B5B63131DAA3200F48D02 /* CookiesStrategy.h in Headers */,
 				33D0212D131DB37B004091A8 /* CookieStorage.h in Headers */,
 				5120BBAF1F1CECE700EFEBF1 /* CookieStorageObserver.h in Headers */,

Modified: trunk/Source/WebCore/loader/CookieJar.cpp (230874 => 230875)


--- trunk/Source/WebCore/loader/CookieJar.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/loader/CookieJar.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-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
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "CookieJar.h"
 
+#include "CookieRequestHeaderFieldProxy.h"
 #include "CookiesStrategy.h"
 #include "Document.h"
 #include "Frame.h"
@@ -55,11 +56,17 @@
     return context ? context->storageSession() : NetworkStorageSession::defaultStorageSession();
 }
 
+static IncludeSecureCookies shouldIncludeSecureCookies(const Document& document, const URL& url)
+{
+    return (url.protocolIs("https") && !document.foundMixedContent().contains(SecurityContext::MixedContentType::Active)) ? IncludeSecureCookies::Yes : IncludeSecureCookies::No;
+}
+
 String cookies(Document& document, const URL& url)
 {
     TraceScope scope(FetchCookiesStart, FetchCookiesEnd);
 
-    auto includeSecureCookies = (url.protocolIs("https") && !document.foundMixedContent().contains(SecurityContext::MixedContentType::Active)) ? IncludeSecureCookies::Yes : IncludeSecureCookies::No;
+    auto includeSecureCookies = shouldIncludeSecureCookies(document, url);
+
     std::pair<String, bool> result;
     auto frame = document.frame();
     if (frame)
@@ -73,6 +80,18 @@
     return result.first;
 }
 
+CookieRequestHeaderFieldProxy cookieRequestHeaderFieldProxy(const Document& document, const URL& url)
+{
+    TraceScope scope(FetchCookiesStart, FetchCookiesEnd);
+
+    auto includeSecureCookies = shouldIncludeSecureCookies(document, url);
+
+    if (auto* frame = document.frame())
+        return { storageSession(document).sessionID(), document.firstPartyForCookies(), url, frame->loader().client().frameID(), frame->loader().client().pageID(), includeSecureCookies };
+
+    return { storageSession(document).sessionID(), document.firstPartyForCookies(), url, std::nullopt, std::nullopt, includeSecureCookies };
+}
+
 void setCookies(Document& document, const URL& url, const String& cookieString)
 {
     auto frame = document.frame();
@@ -89,7 +108,8 @@
 
 String cookieRequestHeaderFieldValue(Document& document, const URL& url)
 {
-    auto includeSecureCookies = (url.protocolIs("https") && !document.foundMixedContent().contains(SecurityContext::MixedContentType::Active)) ? IncludeSecureCookies::Yes : IncludeSecureCookies::No;
+    auto includeSecureCookies = shouldIncludeSecureCookies(document, url);
+
     std::pair<String, bool> result;
     auto frame = document.frame();
     if (frame)

Modified: trunk/Source/WebCore/loader/CookieJar.h (230874 => 230875)


--- trunk/Source/WebCore/loader/CookieJar.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/loader/CookieJar.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-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
@@ -33,6 +33,7 @@
 class Document;
 class URL;
 struct Cookie;
+struct CookieRequestHeaderFieldProxy;
 
 // Functions in this file take a Document pointer to determine which cookie storage to use. We should merge that into call sites, and use PlatformCookieJar directly.
 
@@ -42,6 +43,7 @@
 
 WEBCORE_EXPORT bool cookiesEnabled(const Document&);
 WEBCORE_EXPORT String cookieRequestHeaderFieldValue(Document&, const URL&);
+WEBCORE_EXPORT CookieRequestHeaderFieldProxy cookieRequestHeaderFieldProxy(const Document&, const URL&);
 WEBCORE_EXPORT bool getRawCookies(const Document&, const URL&, Vector<Cookie>&);
 WEBCORE_EXPORT void deleteCookie(const Document&, const URL&, const String& cookieName);
 

Added: trunk/Source/WebCore/platform/network/CookieRequestHeaderFieldProxy.h (0 => 230875)


--- trunk/Source/WebCore/platform/network/CookieRequestHeaderFieldProxy.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/network/CookieRequestHeaderFieldProxy.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -0,0 +1,108 @@
+/*
+ * 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 met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CookiesStrategy.h"
+#include "URL.h"
+#include <pal/SessionID.h>
+
+namespace WebCore {
+
+struct CookieRequestHeaderFieldProxy {
+    PAL::SessionID m_sessionID;
+    URL m_firstParty;
+    URL m_url;
+    std::optional<uint64_t> m_frameID;
+    std::optional<uint64_t> m_pageID;
+    IncludeSecureCookies m_includeSecureCookies { IncludeSecureCookies::No };
+
+    CookieRequestHeaderFieldProxy() = default;
+    CookieRequestHeaderFieldProxy(PAL::SessionID&& sessionID, URL&& firstParty, URL&& url, std::optional<uint64_t>&& frameID, std::optional<uint64_t>&& pageID, IncludeSecureCookies includeSecureCookies)
+        : m_sessionID(WTFMove(sessionID))
+        , m_firstParty(WTFMove(firstParty))
+        , m_url(WTFMove(url))
+        , m_frameID(WTFMove(frameID))
+        , m_pageID(WTFMove(pageID))
+        , m_includeSecureCookies(includeSecureCookies)
+    {
+    }
+
+    CookieRequestHeaderFieldProxy(PAL::SessionID sessionID, const URL& firstParty, const URL& url, const std::optional<uint64_t>& frameID, const std::optional<uint64_t>& pageID, IncludeSecureCookies includeSecureCookies)
+        : m_sessionID(sessionID)
+        , m_firstParty(firstParty)
+        , m_url(url)
+        , m_frameID(frameID)
+        , m_pageID(pageID)
+        , m_includeSecureCookies(includeSecureCookies)
+    {
+    }
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static std::optional<CookieRequestHeaderFieldProxy> decode(Decoder&);
+};
+
+template<class Encoder>
+void CookieRequestHeaderFieldProxy::encode(Encoder& encoder) const
+{
+    encoder << m_sessionID;
+    encoder << m_firstParty;
+    encoder << m_url;
+    encoder << m_frameID;
+    encoder << m_pageID;
+    encoder << m_includeSecureCookies;
+}
+
+template<class Decoder>
+std::optional<CookieRequestHeaderFieldProxy> CookieRequestHeaderFieldProxy::decode(Decoder& decoder)
+{
+    PAL::SessionID sessionID;
+    if (!decoder.decode(sessionID))
+        return std::nullopt;
+
+    URL firstParty;
+    if (!decoder.decode(firstParty))
+        return std::nullopt;
+
+    URL url;
+    if (!decoder.decode(url))
+        return std::nullopt;
+
+    std::optional<uint64_t> frameID;
+    if (!decoder.decode(frameID))
+        return std::nullopt;
+
+    std::optional<uint64_t> pageID;
+    if (!decoder.decode(pageID))
+        return std::nullopt;
+
+    IncludeSecureCookies includeSecureCookies;
+    if (!decoder.decode(includeSecureCookies))
+        return std::nullopt;
+
+    return {{ WTFMove(sessionID), WTFMove(firstParty), WTFMove(url), WTFMove(*frameID), WTFMove(*pageID), includeSecureCookies }};
+}
+
+}

Modified: trunk/Source/WebCore/platform/network/PlatformCookieJar.h (230874 => 230875)


--- trunk/Source/WebCore/platform/network/PlatformCookieJar.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/PlatformCookieJar.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -36,6 +36,7 @@
 class NetworkStorageSession;
 
 struct Cookie;
+struct CookieRequestHeaderFieldProxy;
 
 enum class IncludeSecureCookies;
 
@@ -45,6 +46,7 @@
 WEBCORE_EXPORT void setCookiesFromDOM(const NetworkStorageSession&, const URL& firstParty, const URL&, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, const String&);
 WEBCORE_EXPORT bool cookiesEnabled(const NetworkStorageSession&);
 WEBCORE_EXPORT std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession&, const URL& firstParty, const URL&, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, IncludeSecureCookies);
+WEBCORE_EXPORT std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession&, const CookieRequestHeaderFieldProxy&);
 WEBCORE_EXPORT bool getRawCookies(const NetworkStorageSession&, const URL& firstParty, const URL&, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, Vector<Cookie>&);
 WEBCORE_EXPORT void deleteCookie(const NetworkStorageSession&, const URL&, const String&);
 WEBCORE_EXPORT void getHostnamesWithCookies(const NetworkStorageSession&, HashSet<String>& hostnames);

Modified: trunk/Source/WebCore/platform/network/SocketStreamHandle.cpp (230874 => 230875)


--- trunk/Source/WebCore/platform/network/SocketStreamHandle.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/SocketStreamHandle.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "SocketStreamHandle.h"
 
+#include "CookieRequestHeaderFieldProxy.h"
 #include "SocketStreamHandleClient.h"
 #include <wtf/Function.h>
 
@@ -52,9 +53,16 @@
 {
     if (m_state == Connecting || m_state == Closing)
         return completionHandler(false);
-    platformSend(data, length, WTFMove(completionHandler));
+    platformSend(reinterpret_cast<const uint8_t*>(data), length, WTFMove(completionHandler));
 }
 
+void SocketStreamHandle::sendHandshake(CString&& handshake, std::optional<CookieRequestHeaderFieldProxy>&& headerFieldProxy, Function<void(bool, bool)> completionHandler)
+{
+    if (m_state == Connecting || m_state == Closing)
+        return completionHandler(false, false);
+    platformSendHandshake(reinterpret_cast<const uint8_t*>(handshake.data()), handshake.length(), headerFieldProxy, WTFMove(completionHandler));
+}
+
 void SocketStreamHandle::close()
 {
     if (m_state == Closed)

Modified: trunk/Source/WebCore/platform/network/SocketStreamHandle.h (230874 => 230875)


--- trunk/Source/WebCore/platform/network/SocketStreamHandle.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/SocketStreamHandle.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -36,6 +36,7 @@
 
 namespace WebCore {
 
+struct CookieRequestHeaderFieldProxy;
 class SocketStreamHandleClient;
 
 typedef struct {
@@ -53,6 +54,7 @@
     SocketStreamState state() const;
 
     void sendData(const char* data, size_t length, Function<void(bool)>);
+    void sendHandshake(CString&& handshake, std::optional<CookieRequestHeaderFieldProxy>&&, Function<void(bool, bool)>);
     void close(); // Disconnect after all data in buffer are sent.
     void disconnect();
     virtual size_t bufferedAmount() = 0;
@@ -60,7 +62,8 @@
 protected:
     WEBCORE_EXPORT SocketStreamHandle(const URL&, SocketStreamHandleClient&);
 
-    virtual void platformSend(const char* data, size_t length, Function<void(bool)>&&) = 0;
+    virtual void platformSend(const uint8_t* data, size_t length, Function<void(bool)>&&) = 0;
+    virtual void platformSendHandshake(const uint8_t* data, size_t length, const std::optional<CookieRequestHeaderFieldProxy>&, Function<void(bool, bool)>&&) = 0;
     virtual void platformClose() = 0;
 
     URL m_url;

Modified: trunk/Source/WebCore/platform/network/SocketStreamHandleImpl.cpp (230874 => 230875)


--- trunk/Source/WebCore/platform/network/SocketStreamHandleImpl.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/SocketStreamHandleImpl.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -26,12 +26,15 @@
 #include "config.h"
 #include "SocketStreamHandleImpl.h"
 
+#include "CookieRequestHeaderFieldProxy.h"
+#include "NetworkStorageSession.h"
+#include "PlatformCookieJar.h"
 #include "SocketStreamHandleClient.h"
 #include <wtf/Function.h>
 
 namespace WebCore {
 
-void SocketStreamHandleImpl::platformSend(const char* data, size_t length, Function<void(bool)>&& completionHandler)
+void SocketStreamHandleImpl::platformSend(const uint8_t* data, size_t length, Function<void(bool)>&& completionHandler)
 {
     if (!m_buffer.isEmpty()) {
         if (m_buffer.size() + length > maxBufferSize) {
@@ -60,6 +63,90 @@
     return completionHandler(true);
 }
 
+static size_t removeTerminationCharacters(const uint8_t* data, size_t dataLength)
+{
+#ifndef NDEBUG
+    ASSERT(dataLength > 2);
+    ASSERT(data[dataLength - 2] == '\r');
+    ASSERT(data[dataLength - 1] == '\n');
+#else
+    UNUSED_PARAM(data);
+#endif
+
+    // Remove the terminating '\r\n'
+    return dataLength - 2;
+}
+
+static std::pair<Vector<uint8_t>, bool> cookieDataForHandshake(const CookieRequestHeaderFieldProxy& headerFieldProxy)
+{
+    auto networkStorageSession = NetworkStorageSession::storageSession(headerFieldProxy.m_sessionID);
+    RELEASE_ASSERT(networkStorageSession);
+
+    String cookieDataString;
+    bool secureCookiesAccessed = false;
+    std::tie(cookieDataString, secureCookiesAccessed) = WebCore::cookieRequestHeaderFieldValue(*networkStorageSession, headerFieldProxy);
+    if (cookieDataString.isEmpty())
+        return { { }, secureCookiesAccessed };
+
+    CString cookieData = cookieDataString.utf8();
+
+    Vector<uint8_t> data = { 'C', 'o', 'o', 'k', 'i', 'e', ':', ' ' };
+    data.append(cookieData.data(), cookieData.length());
+    data.appendVector(Vector<uint8_t>({ '\r', '\n', '\r', '\n' }));
+
+    return { data, secureCookiesAccessed };
+}
+
+void SocketStreamHandleImpl::platformSendHandshake(const uint8_t* data, size_t length, const std::optional<CookieRequestHeaderFieldProxy>& headerFieldProxy, Function<void(bool, bool)>&& completionHandler)
+{
+    Vector<uint8_t> cookieData;
+    bool secureCookiesAccessed = false;
+
+    if (headerFieldProxy) {
+        std::tie(cookieData, secureCookiesAccessed) = cookieDataForHandshake(headerFieldProxy.value());
+        if (cookieData.size())
+            length = removeTerminationCharacters(data, length);
+    }
+
+    if (!m_buffer.isEmpty()) {
+        if (m_buffer.size() + length + cookieData.size() > maxBufferSize) {
+            // FIXME: report error to indicate that buffer has no more space.
+            return completionHandler(false, secureCookiesAccessed);
+        }
+        m_buffer.append(data, length);
+        m_buffer.append(cookieData.data(), cookieData.size());
+        m_client.didUpdateBufferedAmount(*this, bufferedAmount());
+        return completionHandler(true, secureCookiesAccessed);
+    }
+    size_t bytesWritten = 0;
+    if (m_state == Open) {
+        // Unfortunately, we need to send the data in one buffer or else the handshake fails.
+        Vector<uint8_t> sendData;
+        sendData.reserveCapacity(length + cookieData.size());
+        sendData.append(data, length);
+        sendData.append(cookieData.data(), cookieData.size());
+
+        if (auto result = platformSendInternal(sendData.data(), sendData.size()))
+            bytesWritten = result.value();
+        else
+            return completionHandler(false, secureCookiesAccessed);
+    }
+    if (m_buffer.size() + length + cookieData.size() - bytesWritten > maxBufferSize) {
+        // FIXME: report error to indicate that buffer has no more space.
+        return completionHandler(false, secureCookiesAccessed);
+    }
+    if (bytesWritten < length + cookieData.size()) {
+        size_t cookieBytesWritten = 0;
+        if (bytesWritten < length)
+            m_buffer.append(data + bytesWritten, length - bytesWritten);
+        else
+            cookieBytesWritten = bytesWritten - length;
+        m_buffer.append(cookieData.data() + cookieBytesWritten, cookieData.size() - cookieBytesWritten);
+        m_client.didUpdateBufferedAmount(static_cast<SocketStreamHandle&>(*this), bufferedAmount());
+    }
+    return completionHandler(true, secureCookiesAccessed);
+}
+
 bool SocketStreamHandleImpl::sendPendingData()
 {
     if (m_state != Open && m_state != Closing)

Modified: trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h (230874 => 230875)


--- trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImpl.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -50,11 +50,12 @@
 
     virtual ~SocketStreamHandleImpl();
 
-    WEBCORE_EXPORT void platformSend(const char* data, size_t length, Function<void(bool)>&&) final;
+    WEBCORE_EXPORT void platformSend(const uint8_t* data, size_t length, Function<void(bool)>&&) final;
+    WEBCORE_EXPORT void platformSendHandshake(const uint8_t* data, size_t length, const std::optional<CookieRequestHeaderFieldProxy>&, Function<void(bool, bool)>&&) final;
     WEBCORE_EXPORT void platformClose() final;
 private:
     size_t bufferedAmount() final;
-    std::optional<size_t> platformSendInternal(const char*, size_t);
+    std::optional<size_t> platformSendInternal(const uint8_t*, size_t);
     bool sendPendingData();
 
     WEBCORE_EXPORT SocketStreamHandleImpl(const URL&, SocketStreamHandleClient&, PAL::SessionID, const String& credentialPartition, SourceApplicationAuditToken&&);
@@ -103,7 +104,7 @@
     String m_credentialPartition;
     SourceApplicationAuditToken m_auditData;
 
-    StreamBuffer<char, 1024 * 1024> m_buffer;
+    StreamBuffer<uint8_t, 1024 * 1024> m_buffer;
     static const unsigned maxBufferSize = 100 * 1024 * 1024;
 };
 

Modified: trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp (230874 => 230875)


--- trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -696,7 +696,7 @@
     ASSERT(!m_pacRunLoopSource);
 }
 
-std::optional<size_t> SocketStreamHandleImpl::platformSendInternal(const char* data, size_t length)
+std::optional<size_t> SocketStreamHandleImpl::platformSendInternal(const uint8_t* data, size_t length)
 {
     if (!m_writeStream)
         return 0;

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


--- trunk/Source/WebCore/platform/network/curl/CookieJarCurl.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarCurl.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -22,6 +22,7 @@
 
 #if USE(CURL)
 #include "Cookie.h"
+#include "CookieRequestHeaderFieldProxy.h"
 #include "NetworkStorageSession.h"
 #include "URL.h"
 
@@ -44,6 +45,11 @@
     return session.cookieStorage().cookieRequestHeaderFieldValue(session, firstParty, url, frameID, pageID, includeSecureCookies);
 }
 
+std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const CookieRequestHeaderFieldProxy& headerFieldProxy)
+{
+    return session.cookieStorage().cookieRequestHeaderFieldValue(session, headerFieldProxy.m_firstParty, headerFieldProxy.m_url, headerFieldProxy.m_frameID, headerFieldProxy.m_pageID, headerFieldProxy.m_includeSecureCookies);
+}
+
 bool cookiesEnabled(const NetworkStorageSession& session)
 {
     return session.cookieStorage().cookiesEnabled(session);

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


--- trunk/Source/WebCore/platform/network/curl/CookieJarCurl.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarCurl.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -23,6 +23,7 @@
 namespace WebCore {
 
 struct Cookie;
+struct CookieRequestHeaderFieldProxy;
 class NetworkStorageSession;
 class URL;
 
@@ -33,6 +34,7 @@
     virtual void setCookiesFromHTTPResponse(const NetworkStorageSession&, const URL&, const String&) const = 0;
     virtual bool cookiesEnabled(const NetworkStorageSession&) const = 0;
     virtual std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession&, const URL& firstParty, const URL&, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, IncludeSecureCookies) const = 0;
+    virtual std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession&, const CookieRequestHeaderFieldProxy&) const = 0;
     virtual bool getRawCookies(const NetworkStorageSession&, const URL& firstParty, const URL&, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, Vector<Cookie>&) const = 0;
     virtual void deleteCookie(const NetworkStorageSession&, const URL&, const String&) const = 0;
     virtual void getHostnamesWithCookies(const NetworkStorageSession&, HashSet<String>& hostnames) const = 0;

Modified: trunk/Source/WebCore/platform/network/curl/CookieJarCurlDatabase.cpp (230874 => 230875)


--- trunk/Source/WebCore/platform/network/curl/CookieJarCurlDatabase.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarCurlDatabase.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -93,6 +93,11 @@
     return { cookiesForSession(session, firstParty, url, true), false };
 }
 
+std::pair<String, bool> CookieJarCurlDatabase::cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const CookieRequestHeaderFieldProxy& headerFieldProxy) const
+{
+    return cookieRequestHeaderFieldValue(session, headerFieldProxy.m_firstParty, headerFieldProxy.m_url, headerFieldProxy.m_frameID, headerFieldProxy.m_pageID, headerFieldProxy.m_includeSecureCookies);    
+}
+
 bool CookieJarCurlDatabase::cookiesEnabled(const NetworkStorageSession& session) const
 {
     return session.cookieDatabase().isEnabled();

Modified: trunk/Source/WebCore/platform/network/curl/CookieJarCurlDatabase.h (230874 => 230875)


--- trunk/Source/WebCore/platform/network/curl/CookieJarCurlDatabase.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/curl/CookieJarCurlDatabase.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -34,6 +34,7 @@
     void setCookiesFromHTTPResponse(const NetworkStorageSession&, const URL&, const String&) const override;
     bool cookiesEnabled(const NetworkStorageSession&) const override;
     std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession&, const URL& firstParty, const URL&, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, IncludeSecureCookies) const override;
+    std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession&, const CookieRequestHeaderFieldProxy&) const override;
     bool getRawCookies(const NetworkStorageSession&, const URL& firstParty, const URL&, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, Vector<Cookie>&) const override;
     void deleteCookie(const NetworkStorageSession&, const URL&, const String&) const override;
     void getHostnamesWithCookies(const NetworkStorageSession&, HashSet<String>& hostnames) const override;

Modified: trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h (230874 => 230875)


--- trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2018 Apple Inc. All rights reserved.
  * Copyright (C) 2009 Google Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -57,13 +57,14 @@
 
     virtual ~SocketStreamHandleImpl();
 
-    WEBCORE_EXPORT void platformSend(const char* data, size_t length, Function<void(bool)>&&) final;
+    WEBCORE_EXPORT void platformSend(const uint8_t* data, size_t length, Function<void(bool)>&&) final;
+    WEBCORE_EXPORT void platformSendHandshake(const uint8_t* data, size_t length, const std::optional<CookieRequestHeaderFieldProxy>&, Function<void(bool, bool)>&&) final;
     WEBCORE_EXPORT void platformClose() final;
 private:
     WEBCORE_EXPORT SocketStreamHandleImpl(const URL&, SocketStreamHandleClient&);
 
     size_t bufferedAmount() final;
-    std::optional<size_t> platformSendInternal(const char*, size_t);
+    std::optional<size_t> platformSendInternal(const uint8_t*, size_t);
     bool sendPendingData();
 
     bool readData(CURL*);
@@ -102,7 +103,7 @@
     Deque<SocketData> m_receiveData;
     bool m_closed { false };
 
-    StreamBuffer<char, 1024 * 1024> m_buffer;
+    StreamBuffer<uint8_t, 1024 * 1024> m_buffer;
     static const unsigned maxBufferSize = 100 * 1024 * 1024;
 };
 

Modified: trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp (230874 => 230875)


--- trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -66,7 +66,7 @@
     ASSERT(!m_workerThread);
 }
 
-std::optional<size_t> SocketStreamHandleImpl::platformSendInternal(const char* data, size_t length)
+std::optional<size_t> SocketStreamHandleImpl::platformSendInternal(const uint8_t* data, size_t length)
 {
     LOG(Network, "SocketStreamHandle %p platformSend", this);
 
@@ -74,7 +74,7 @@
 
     startThread();
 
-    auto copy = createCopy(data, length);
+    auto copy = createCopy(reinterpret_cast<const char*>(data), length);
 
     std::lock_guard<Lock> lock(m_mutexSend);
     m_sendData.append(SocketData { WTFMove(copy), length });

Modified: trunk/Source/WebCore/platform/network/mac/CookieJarMac.mm (230874 => 230875)


--- trunk/Source/WebCore/platform/network/mac/CookieJarMac.mm	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/mac/CookieJarMac.mm	2018-04-21 01:51:37 UTC (rev 230875)
@@ -26,6 +26,7 @@
 #import "config.h"
 #import "PlatformCookieJar.h"
 
+#import "CookieRequestHeaderFieldProxy.h"
 #import "CookiesStrategy.h"
 #import "NetworkStorageSession.h"
 #import <pal/spi/cf/CFNetworkSPI.h>
@@ -251,6 +252,11 @@
     return cookiesForSession(session, firstParty, url, frameID, pageID, IncludeHTTPOnly, includeSecureCookies);
 }
 
+std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const CookieRequestHeaderFieldProxy& headerFieldProxy)
+{
+    return cookiesForSession(session, headerFieldProxy.m_firstParty, headerFieldProxy.m_url, headerFieldProxy.m_frameID, headerFieldProxy.m_pageID, IncludeHTTPOnly, headerFieldProxy.m_includeSecureCookies);
+}
+
 void setCookiesFromDOM(const NetworkStorageSession& session, const URL& firstParty, const URL& url, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, const String& cookieStr)
 {
     ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));

Modified: trunk/Source/WebCore/platform/network/soup/CookieJarSoup.cpp (230874 => 230875)


--- trunk/Source/WebCore/platform/network/soup/CookieJarSoup.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/soup/CookieJarSoup.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -23,6 +23,7 @@
 #if USE(SOUP)
 
 #include "Cookie.h"
+#include "CookieRequestHeaderFieldProxy.h"
 #include "CookiesStrategy.h"
 #include "GUniquePtrSoup.h"
 #include "NetworkStorageSession.h"
@@ -133,6 +134,11 @@
     return cookiesForSession(session, url, true, includeSecureCookies);
 }
 
+std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const CookieRequestHeaderFieldProxy& headerFieldProxy)
+{
+    return cookieRequestHeaderFieldValue(session, headerFieldProxy.m_firstParty, headerFieldProxy.m_url, headerFieldProxy.m_frameID, headerFieldProxy.m_pageID, headerFieldProxy.m_includeSecureCookies);
+}
+
 bool cookiesEnabled(const NetworkStorageSession& session)
 {
     auto policy = soup_cookie_jar_get_accept_policy(session.cookieStorage());

Modified: trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h (230874 => 230875)


--- trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2018 Apple Inc. All rights reserved.
  * Copyright (C) 2009 Google Inc.  All rights reserved.
  * Copyright (C) 2012 Samsung Electronics Ltd. All Rights Reserved.
  *
@@ -51,13 +51,14 @@
     static Ref<SocketStreamHandleImpl> create(const URL&, SocketStreamHandleClient&, PAL::SessionID, const String&, SourceApplicationAuditToken&&);
     virtual ~SocketStreamHandleImpl();
 
-    void platformSend(const char* data, size_t length, Function<void(bool)>&&) final;
+    void platformSend(const uint8_t* data, size_t length, Function<void(bool)>&&) final;
+    void platformSendHandshake(const uint8_t* data, size_t length, const std::optional<CookieRequestHeaderFieldProxy>&, Function<void(bool, bool)>&&) final;
     void platformClose() final;
 private:
     SocketStreamHandleImpl(const URL&, SocketStreamHandleClient&);
 
     size_t bufferedAmount() final;
-    std::optional<size_t> platformSendInternal(const char*, size_t);
+    std::optional<size_t> platformSendInternal(const uint8_t*, size_t);
     bool sendPendingData();
 
     void beginWaitingForSocketWritability();
@@ -79,7 +80,7 @@
     GRefPtr<GCancellable> m_cancellable;
     UniqueArray<char> m_readBuffer;
 
-    StreamBuffer<char, 1024 * 1024> m_buffer;
+    StreamBuffer<uint8_t, 1024 * 1024> m_buffer;
     static const unsigned maxBufferSize = 100 * 1024 * 1024;
 };
 

Modified: trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp (230874 => 230875)


--- trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -212,7 +212,7 @@
     sendPendingData();
 }
 
-std::optional<size_t> SocketStreamHandleImpl::platformSendInternal(const char* data, size_t length)
+std::optional<size_t> SocketStreamHandleImpl::platformSendInternal(const uint8_t* data, size_t length)
 {
     LOG(Network, "SocketStreamHandle %p platformSend", this);
     if (!m_outputStream || !data)
@@ -219,7 +219,7 @@
         return 0;
 
     GUniqueOutPtr<GError> error;
-    gssize written = g_pollable_output_stream_write_nonblocking(m_outputStream.get(), data, length, m_cancellable.get(), &error.outPtr());
+    gssize written = g_pollable_output_stream_write_nonblocking(m_outputStream.get(), reinterpret_cast<const char*>(data), length, m_cancellable.get(), &error.outPtr());
     if (error) {
         if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
             beginWaitingForSocketWritability();

Modified: trunk/Source/WebKit/ChangeLog (230874 => 230875)


--- trunk/Source/WebKit/ChangeLog	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebKit/ChangeLog	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,3 +1,30 @@
+2018-04-20  Brent Fulgham  <bfulg...@apple.com>
+
+        Limit cookie header access to Network process
+        https://bugs.webkit.org/show_bug.cgi?id=184764
+        <rdar://problem/36785285>
+
+        Reviewed by Youenn Fablet.
+
+        Revise the handling of cookie request headers so that we don't interact with them in the
+        WebContent process. They are only needed for interaction with the server and the network
+        process, so we should limit their scope to just the Network process.
+
+        Instead, we should handle a token that represents the cookie headers in the WebContent
+        process, which can be converted to the relevant cookie data in the network process when
+        needed.
+
+        * NetworkProcess/NetworkSocketStream.cpp:
+        (WebKit::NetworkSocketStream::sendHandshake):
+        * NetworkProcess/NetworkSocketStream.h:
+        * NetworkProcess/NetworkSocketStream.messages.in:
+        * WebProcess/Network/WebSocketStream.cpp:
+        (WebKit::WebSocketStream::networkProcessCrashed):
+        (WebKit::WebSocketStream::platformSendHandshake):
+        (WebKit::WebSocketStream::didSendHandshake):
+        * WebProcess/Network/WebSocketStream.h:
+        * WebProcess/Network/WebSocketStream.messages.in:
+
 2018-04-20  Jeremy Jones  <jere...@apple.com>
 
         Disable backward and forward navigation swipes while in fullscreen.

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp (230874 => 230875)


--- trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -28,6 +28,7 @@
 
 #include "DataReference.h"
 #include "WebSocketStreamMessages.h"
+#include <WebCore/CookieRequestHeaderFieldProxy.h>
 #include <WebCore/SocketStreamError.h>
 #include <WebCore/SocketStreamHandleImpl.h>
 
@@ -49,11 +50,18 @@
 
 void NetworkSocketStream::sendData(const IPC::DataReference& data, uint64_t identifier)
 {
-    m_impl->platformSend(reinterpret_cast<const char *>(data.data()), data.size(), [this, protectedThis = makeRef(*this), identifier] (bool success) {
+    m_impl->platformSend(data.data(), data.size(), [this, protectedThis = makeRef(*this), identifier] (bool success) {
         send(Messages::WebSocketStream::DidSendData(identifier, success));
     });
 }
 
+void NetworkSocketStream::sendHandshake(const IPC::DataReference& data, const std::optional<CookieRequestHeaderFieldProxy>& headerFieldProxy, uint64_t identifier)
+{
+    m_impl->platformSendHandshake(data.data(), data.size(), headerFieldProxy, [this, protectedThis = makeRef(*this), identifier] (bool success, bool didAccessSecureCookies) {
+        send(Messages::WebSocketStream::DidSendHandshake(identifier, success, didAccessSecureCookies));
+    });
+}
+
 void NetworkSocketStream::close()
 {
     m_impl->platformClose();

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.h (230874 => 230875)


--- trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -52,6 +52,7 @@
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
 
     void sendData(const IPC::DataReference&, uint64_t);
+    void sendHandshake(const IPC::DataReference&, const std::optional<WebCore::CookieRequestHeaderFieldProxy>&, uint64_t);
     void close();
     
     // SocketStreamHandleClient

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.messages.in (230874 => 230875)


--- trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.messages.in	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSocketStream.messages.in	2018-04-21 01:51:37 UTC (rev 230875)
@@ -22,5 +22,6 @@
 
 messages -> NetworkSocketStream {
     SendData(IPC::DataReference data, uint64_t identifier)
+    SendHandshake(IPC::DataReference data, std::optional<WebCore::CookieRequestHeaderFieldProxy> headerFieldProxy, uint64_t identifier)
     Close()
 }

Modified: trunk/Source/WebKit/WebProcess/Network/WebSocketStream.cpp (230874 => 230875)


--- trunk/Source/WebKit/WebProcess/Network/WebSocketStream.cpp	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebKit/WebProcess/Network/WebSocketStream.cpp	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -32,6 +32,7 @@
 #include "NetworkSocketStreamMessages.h"
 #include "WebCoreArgumentCoders.h"
 #include "WebProcess.h"
+#include <WebCore/CookieRequestHeaderFieldProxy.h>
 #include <WebCore/SocketStreamError.h>
 #include <WebCore/SocketStreamHandleClient.h>
 #include <pal/SessionID.h>
@@ -57,6 +58,8 @@
     for (auto& stream : globalWebSocketStreamMap().values()) {
         for (auto& callback : stream->m_sendDataCallbacks.values())
             callback(false);
+        for (auto& callback : stream->m_sendHandshakeCallbacks.values())
+            callback(false, false);
         stream->m_client.didFailSocketStream(*stream, SocketStreamError(0, { }, "Network process crashed."));
     }
 
@@ -94,21 +97,36 @@
     return identifier();
 }
 
-void WebSocketStream::platformSend(const char* data, size_t length, Function<void(bool)>&& completionHandler)
+void WebSocketStream::platformSend(const uint8_t* data, size_t length, Function<void(bool)>&& completionHandler)
 {
     static uint64_t nextDataIdentifier = 1;
     uint64_t dataIdentifier = nextDataIdentifier++;
-    send(Messages::NetworkSocketStream::SendData(IPC::DataReference(reinterpret_cast<const uint8_t *>(data), length), dataIdentifier));
+    send(Messages::NetworkSocketStream::SendData(IPC::DataReference(data, length), dataIdentifier));
     ASSERT(!m_sendDataCallbacks.contains(dataIdentifier));
-    m_sendDataCallbacks.set(dataIdentifier, WTFMove(completionHandler));
+    m_sendDataCallbacks.add(dataIdentifier, WTFMove(completionHandler));
 }
 
+void WebSocketStream::platformSendHandshake(const uint8_t* data, size_t length, const std::optional<CookieRequestHeaderFieldProxy>& headerFieldProxy, Function<void(bool, bool)>&& completionHandler)
+{
+    static uint64_t nextDataIdentifier = 1;
+    uint64_t dataIdentifier = nextDataIdentifier++;
+    send(Messages::NetworkSocketStream::SendHandshake(IPC::DataReference(data, length), headerFieldProxy, dataIdentifier));
+    ASSERT(!m_sendHandshakeCallbacks.contains(dataIdentifier));
+    m_sendHandshakeCallbacks.add(dataIdentifier, WTFMove(completionHandler));
+}
+
 void WebSocketStream::didSendData(uint64_t identifier, bool success)
 {
     ASSERT(m_sendDataCallbacks.contains(identifier));
     m_sendDataCallbacks.take(identifier)(success);
 }
-    
+
+void WebSocketStream::didSendHandshake(uint64_t identifier, bool success, bool didAccessSecureCookies)
+{
+    ASSERT(m_sendHandshakeCallbacks.contains(identifier));
+    m_sendHandshakeCallbacks.take(identifier)(success, didAccessSecureCookies);
+}
+
 void WebSocketStream::platformClose()
 {
     send(Messages::NetworkSocketStream::Close());

Modified: trunk/Source/WebKit/WebProcess/Network/WebSocketStream.h (230874 => 230875)


--- trunk/Source/WebKit/WebProcess/Network/WebSocketStream.h	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebKit/WebProcess/Network/WebSocketStream.h	2018-04-21 01:51:37 UTC (rev 230875)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-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
@@ -52,7 +52,8 @@
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
     
     // SocketStreamHandle
-    void platformSend(const char*, size_t, Function<void(bool)>&&) final;
+    void platformSend(const uint8_t*, size_t, Function<void(bool)>&&) final;
+    void platformSendHandshake(const uint8_t*, size_t, const std::optional<WebCore::CookieRequestHeaderFieldProxy>&, Function<void(bool, bool)>&&);
     void platformClose() final;
     size_t bufferedAmount() final;
 
@@ -64,7 +65,8 @@
     void didUpdateBufferedAmount(uint64_t);
     void didFailSocketStream(WebCore::SocketStreamError&&);
 
-    void didSendData(uint64_t, bool);
+    void didSendData(uint64_t, bool success);
+    void didSendHandshake(uint64_t, bool success, bool didAccessSecureCookies);
     
 private:
     // MessageSender
@@ -77,6 +79,7 @@
     size_t m_bufferedAmount { 0 };
     WebCore::SocketStreamHandleClient& m_client;
     HashMap<uint64_t, Function<void(bool)>> m_sendDataCallbacks;
+    HashMap<uint64_t, Function<void(bool, bool)>> m_sendHandshakeCallbacks;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/Network/WebSocketStream.messages.in (230874 => 230875)


--- trunk/Source/WebKit/WebProcess/Network/WebSocketStream.messages.in	2018-04-21 01:36:20 UTC (rev 230874)
+++ trunk/Source/WebKit/WebProcess/Network/WebSocketStream.messages.in	2018-04-21 01:51:37 UTC (rev 230875)
@@ -29,4 +29,5 @@
     DidFailSocketStream(WebCore::SocketStreamError error)
 
     DidSendData(uint64_t identifier, bool success)
+    DidSendHandshake(uint64_t identifier, bool success, bool didAccessSecureCookies)
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to