NetworkResourceLoader does not need to expose all redirect response headers
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Apr 2018 22:20:21 +0000 (22:20 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Apr 2018 22:20:21 +0000 (22:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184114
<rdar://problem/39010557>

Reviewed by Ryosuke Niwa.

Source/WebCore:

No JS observable change of behavior.
Behavior change is observable for injected bundles since they will no longer get access to the full response.
List of response headers correspond to the one currently being used/exposed for redirections.

Test: http/wpt/loading/redirect-headers.html

* page/RuntimeEnabledFeatures.h:
(WebCore::RuntimeEnabledFeatures::setRestrictedHTTPResponseAccess):
(WebCore::RuntimeEnabledFeatures::restrictedHTTPResponseAccess const):
* platform/network/ResourceResponseBase.cpp:
(WebCore::isSafeToKeepRedirectionHeader):
(WebCore::ResourceResponseBase::sanitizeRedirectionHTTPHeaderFields):
* platform/network/ResourceResponseBase.h:

Source/WebKit:

WebProcess instructs NetworkProcess whether to sanitize response headers based on a runtime flag.
We sanitize redirection response headers in case this is not related to a navigation load.
Navigation loads may currently require the full response for content blockers.

* NetworkProcess/NetworkResourceLoadParameters.cpp:
(WebKit::NetworkResourceLoadParameters::encode const):
(WebKit::NetworkResourceLoadParameters::decode):
* NetworkProcess/NetworkResourceLoadParameters.h:
* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::willSendRedirectedRequest):
(WebKit::NetworkResourceLoader::sanitizeRedirectResponseIfPossible):
(WebKit::NetworkResourceLoader::dispatchWillSendRequestForCacheEntry):
* NetworkProcess/NetworkResourceLoader.h:
* Shared/WebPreferences.yaml:
* UIProcess/API/C/WKPreferences.cpp:
(WKPreferencesSetRestrictedHTTPResponseAccess):
(WKPreferencesGetRestrictedHTTPResponseAccess):
* UIProcess/API/C/WKPreferencesRef.h:
* WebProcess/Network/WebLoaderStrategy.cpp:
(WebKit::WebLoaderStrategy::scheduleLoadFromNetworkProcess):
(WebKit::WebLoaderStrategy::loadResourceSynchronously):
(WebKit::WebLoaderStrategy::startPingLoad):
(WebKit::WebLoaderStrategy::preconnectTo):

Tools:

Add an option to dump the number of headers in a response.
This allows validating that filtering does happen or not.

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
(WTR::dumpResponseDescriptionSuitableForTestResult):
(WTR::InjectedBundlePage::responseHeaderCount):
(WTR::InjectedBundlePage::willSendRequestForFrame):
* WebKitTestRunner/InjectedBundle/InjectedBundlePage.h:
* WebKitTestRunner/InjectedBundle/TestRunner.h:
(WTR::TestRunner::dumpAllHTTPRedirectedResponseHeaders):
(WTR::TestRunner::shouldDumpAllHTTPRedirectedResponseHeaders const):
* WebKitTestRunner/InjectedBundle/cocoa/InjectedBundlePageCocoa.mm:
(WTR::InjectedBundlePage::responseHeaderCount):
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::resetPreferencesToConsistentValues):

LayoutTests:

New test verifies that headers are filtered. Witout filtering, 9 headers would be visible to the injected bundle, while 6 headers reamin after filtering.

* http/wpt/loading/redirect-headers-expected.txt: Added.
* http/wpt/loading/redirect-headers.html: Added.
* platform/mac-wk1/TestExpectations: Skipped new test for WK1.

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

25 files changed:
LayoutTests/ChangeLog
LayoutTests/http/wpt/loading/redirect-headers-expected.txt [new file with mode: 0644]
LayoutTests/http/wpt/loading/redirect-headers.html [new file with mode: 0644]
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/win/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/page/RuntimeEnabledFeatures.h
Source/WebCore/platform/network/ResourceResponseBase.cpp
Source/WebCore/platform/network/ResourceResponseBase.h
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp
Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h
Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
Source/WebKit/NetworkProcess/NetworkResourceLoader.h
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/UIProcess/API/C/WKPreferences.cpp
Source/WebKit/UIProcess/API/C/WKPreferencesRef.h
Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/InjectedBundle/cocoa/InjectedBundlePageCocoa.mm
Tools/WebKitTestRunner/TestController.cpp

index 3967b4b..56d3e59 100644 (file)
@@ -1,3 +1,17 @@
+2018-04-03  Youenn Fablet  <youenn@apple.com>
+
+        NetworkResourceLoader does not need to expose all redirect response headers
+        https://bugs.webkit.org/show_bug.cgi?id=184114
+        <rdar://problem/39010557>
+
+        Reviewed by Ryosuke Niwa.
+
+        New test verifies that headers are filtered. Witout filtering, 9 headers would be visible to the injected bundle, while 6 headers reamin after filtering.
+
+        * http/wpt/loading/redirect-headers-expected.txt: Added.
+        * http/wpt/loading/redirect-headers.html: Added.
+        * platform/mac-wk1/TestExpectations: Skipped new test for WK1.
+
 2018-04-03  Ryan Haddad  <ryanhaddad@apple.com>
 
         Mark http/tests/appcache/interrupted-update.html as flaky.
diff --git a/LayoutTests/http/wpt/loading/redirect-headers-expected.txt b/LayoutTests/http/wpt/loading/redirect-headers-expected.txt
new file mode 100644 (file)
index 0000000..febee0d
--- /dev/null
@@ -0,0 +1,11 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+http://localhost:8800/WebKit/beacon/resources/redirect.py?status=302&location=/ - willSendRequest <NSURLRequest URL http://localhost:8800/WebKit/beacon/resources/redirect.py?status=302&location=/, main document URL http://localhost:8800/WebKit/loading/redirect-headers.html, http method GET> redirectResponse (null)
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+http://localhost:8800/WebKit/loading/redirect-headers.html - didFinishLoading
+http://localhost:8800/WebKit/beacon/resources/redirect.py?status=302&location=/ - willSendRequest <NSURLRequest URL http://localhost:8800/?status=302&location=%2F&count=1, main document URL http://localhost:8800/WebKit/loading/redirect-headers.html, http method GET> redirectResponse <NSURLResponse http://localhost:8800/WebKit/beacon/resources/redirect.py?status=302&location=/, http status code 302, 6 headers>
+http://localhost:8800/WebKit/beacon/resources/redirect.py?status=302&location=/ - didReceiveResponse <NSURLResponse http://localhost:8800/?status=302&location=%2F&count=1, http status code 200>
+http://localhost:8800/WebKit/beacon/resources/redirect.py?status=302&location=/ - didFinishLoading
+
diff --git a/LayoutTests/http/wpt/loading/redirect-headers.html b/LayoutTests/http/wpt/loading/redirect-headers.html
new file mode 100644 (file)
index 0000000..eef0126
--- /dev/null
@@ -0,0 +1,18 @@
+<html>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpResourceLoadCallbacks();
+    testRunner.dumpAllHTTPRedirectedResponseHeaders();
+    testRunner.waitUntilDone();
+}
+
+async function doTest()
+{
+    await fetch("../beacon/resources/redirect.py?status=302&location=/");
+    testRunner.notifyDone();
+}
+</script>
+<body onload="doTest();">
+</body>
+</html>
index 670d012..88dc8c7 100644 (file)
@@ -133,6 +133,9 @@ imported/w3c/web-platform-tests/mediacapture-streams
 http/tests/media/media-stream
 http/tests/ssl/media-stream
 
+# WK1 does not filter response headers.
+http/wpt/loading/redirect-headers.html [ Skip ]
+
 # No service worker implementation for WK1
 imported/w3c/web-platform-tests/service-workers [ Skip ]
 http/wpt/service-workers [ Skip ]
index 259a4b8..72aae97 100644 (file)
@@ -3722,6 +3722,8 @@ http/tests/cache-storage [ Skip ]
 http/wpt/cache-storage [ Skip ]
 http/tests/appcache/main-resource-redirect-with-sw.html [ Skip ]
 
+# No header filtering for WK1
+http/wpt/loading/redirect-headers.html [ Skip ]
 
 # Flaky tests on Windows:
 webkit.org/b/176564 http/tests/misc/delete-frame-during-readystatechange.html [ Pass Crash ]
index 54773ed..c88062e 100644 (file)
@@ -1,3 +1,25 @@
+2018-04-03  Youenn Fablet  <youenn@apple.com>
+
+        NetworkResourceLoader does not need to expose all redirect response headers
+        https://bugs.webkit.org/show_bug.cgi?id=184114
+        <rdar://problem/39010557>
+
+        Reviewed by Ryosuke Niwa.
+
+        No JS observable change of behavior.
+        Behavior change is observable for injected bundles since they will no longer get access to the full response.
+        List of response headers correspond to the one currently being used/exposed for redirections.
+
+        Test: http/wpt/loading/redirect-headers.html
+
+        * page/RuntimeEnabledFeatures.h:
+        (WebCore::RuntimeEnabledFeatures::setRestrictedHTTPResponseAccess):
+        (WebCore::RuntimeEnabledFeatures::restrictedHTTPResponseAccess const):
+        * platform/network/ResourceResponseBase.cpp:
+        (WebCore::isSafeToKeepRedirectionHeader):
+        (WebCore::ResourceResponseBase::sanitizeRedirectionHTTPHeaderFields):
+        * platform/network/ResourceResponseBase.h:
+
 2018-04-03  Andy Estes  <aestes@apple.com>
 
         [Mac] Prioritize file promises over filenames during drag and drop
index 8805983..fd7d2b3 100644 (file)
@@ -245,6 +245,9 @@ public:
     void setResourceLoadStatisticsDebugMode(bool isEnabled) { m_resourceLoadStatisticsDebugMode = isEnabled; }
     bool resourceLoadStatisticsDebugMode() const { return m_resourceLoadStatisticsDebugMode; }
 
+    void setRestrictedHTTPResponseAccess(bool isEnabled) { m_isRestrictedHTTPResponseAccess = isEnabled; }
+    bool restrictedHTTPResponseAccess() const { return m_isRestrictedHTTPResponseAccess; }
+
     WEBCORE_EXPORT static RuntimeEnabledFeatures& sharedFeatures();
 
 private:
@@ -375,6 +378,8 @@ private:
     bool m_mediaCapabilitiesEnabled { false };
 
     bool m_resourceLoadStatisticsDebugMode { false };
+
+    bool m_isRestrictedHTTPResponseAccess { false };
     
     friend class WTF::NeverDestroyed<RuntimeEnabledFeatures>;
 };
index 23932d1..4cb0ce8 100644 (file)
@@ -317,6 +317,42 @@ void ResourceResponseBase::setHTTPVersion(const String& versionText)
     // FIXME: Should invalidate or update platform response if present.
 }
 
+static bool isSafeToKeepRedirectionHeader(HTTPHeaderName name)
+{
+    // WebCore needs to keep location and cache related headers as it does caching.
+    // We also keep CORS/ReferrerPolicy headers until CORS checks/Referrer computation are done in NetworkProcess.
+    return name == HTTPHeaderName::Location
+        || name == HTTPHeaderName::ReferrerPolicy
+        || name == HTTPHeaderName::CacheControl
+        || name == HTTPHeaderName::Date
+        || name == HTTPHeaderName::Expires
+        || name == HTTPHeaderName::ETag
+        || name == HTTPHeaderName::LastModified
+        || name == HTTPHeaderName::Age
+        || name == HTTPHeaderName::Pragma
+        || name == HTTPHeaderName::Refresh
+        || name == HTTPHeaderName::Vary
+        || name == HTTPHeaderName::AccessControlAllowCredentials
+        || name == HTTPHeaderName::AccessControlAllowHeaders
+        || name == HTTPHeaderName::AccessControlAllowMethods
+        || name == HTTPHeaderName::AccessControlAllowOrigin
+        || name == HTTPHeaderName::AccessControlExposeHeaders
+        || name == HTTPHeaderName::AccessControlMaxAge
+        || name == HTTPHeaderName::TimingAllowOrigin;
+}
+
+void ResourceResponseBase::sanitizeRedirectionHTTPHeaderFields()
+{
+    lazyInit(AllFields);
+
+    auto commonHeaders = WTFMove(m_httpHeaderFields.commonHeaders());
+    for (auto& header : commonHeaders) {
+        if (isSafeToKeepRedirectionHeader(header.key))
+            m_httpHeaderFields.add(header.key, WTFMove(header.value));
+    }
+    m_httpHeaderFields.uncommonHeaders().clear();
+}
+
 bool ResourceResponseBase::isHTTP09() const
 {
     lazyInit(AllFields);
index 7162602..c63bfad 100644 (file)
@@ -102,6 +102,7 @@ public:
 
     WEBCORE_EXPORT const HTTPHeaderMap& httpHeaderFields() const;
     void setHTTPHeaderFields(HTTPHeaderMap&&);
+    WEBCORE_EXPORT void sanitizeRedirectionHTTPHeaderFields();
 
     String httpHeaderField(const String& name) const;
     WEBCORE_EXPORT String httpHeaderField(HTTPHeaderName) const;
index 8ec8c6d..ba337ba 100644 (file)
@@ -1,5 +1,37 @@
 2018-04-03  Youenn Fablet  <youenn@apple.com>
 
+        NetworkResourceLoader does not need to expose all redirect response headers
+        https://bugs.webkit.org/show_bug.cgi?id=184114
+        <rdar://problem/39010557>
+
+        Reviewed by Ryosuke Niwa.
+
+        WebProcess instructs NetworkProcess whether to sanitize response headers based on a runtime flag.
+        We sanitize redirection response headers in case this is not related to a navigation load.
+        Navigation loads may currently require the full response for content blockers.
+
+        * NetworkProcess/NetworkResourceLoadParameters.cpp:
+        (WebKit::NetworkResourceLoadParameters::encode const):
+        (WebKit::NetworkResourceLoadParameters::decode):
+        * NetworkProcess/NetworkResourceLoadParameters.h:
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::willSendRedirectedRequest):
+        (WebKit::NetworkResourceLoader::sanitizeRedirectResponseIfPossible):
+        (WebKit::NetworkResourceLoader::dispatchWillSendRequestForCacheEntry):
+        * NetworkProcess/NetworkResourceLoader.h:
+        * Shared/WebPreferences.yaml:
+        * UIProcess/API/C/WKPreferences.cpp:
+        (WKPreferencesSetRestrictedHTTPResponseAccess):
+        (WKPreferencesGetRestrictedHTTPResponseAccess):
+        * UIProcess/API/C/WKPreferencesRef.h:
+        * WebProcess/Network/WebLoaderStrategy.cpp:
+        (WebKit::WebLoaderStrategy::scheduleLoadFromNetworkProcess):
+        (WebKit::WebLoaderStrategy::loadResourceSynchronously):
+        (WebKit::WebLoaderStrategy::startPingLoad):
+        (WebKit::WebLoaderStrategy::preconnectTo):
+
+2018-04-03  Youenn Fablet  <youenn@apple.com>
+
         Make NetworkProcess get ContentBlocker information from UIProcess
         https://bugs.webkit.org/show_bug.cgi?id=184205
 
index 44077d3..5d08934 100644 (file)
@@ -95,6 +95,8 @@ void NetworkResourceLoadParameters::encode(IPC::Encoder& encoder) const
     encoder << mainDocumentURL;
     encoder << userContentControllerIdentifier;
 #endif
+
+    encoder << shouldRestrictHTTPResponseAccess;
 }
 
 bool NetworkResourceLoadParameters::decode(IPC::Decoder& decoder, NetworkResourceLoadParameters& result)
@@ -191,6 +193,12 @@ bool NetworkResourceLoadParameters::decode(IPC::Decoder& decoder, NetworkResourc
     result.userContentControllerIdentifier = *userContentControllerIdentifier;
 #endif
 
+    std::optional<bool> shouldRestrictHTTPResponseAccess;
+    decoder >> shouldRestrictHTTPResponseAccess;
+    if (!shouldRestrictHTTPResponseAccess)
+        return false;
+    result.shouldRestrictHTTPResponseAccess = *shouldRestrictHTTPResponseAccess;
+
     return true;
 }
     
index 2cc33ac..2230219 100644 (file)
@@ -58,6 +58,7 @@ public:
     RefPtr<WebCore::SecurityOrigin> sourceOrigin;
     WebCore::FetchOptions::Mode mode;
     std::optional<WebCore::ContentSecurityPolicyResponseHeaders> cspResponseHeaders;
+    bool shouldRestrictHTTPResponseAccess { false };
 
 #if ENABLE(CONTENT_EXTENSIONS)
     WebCore::URL mainDocumentURL;
index 9fa5738..d3ca9cb 100644 (file)
@@ -456,10 +456,17 @@ void NetworkResourceLoader::willSendRedirectedRequest(ResourceRequest&& request,
         continueWillSendRequest(WTFMove(overridenRequest), false);
         return;
     }
-    send(Messages::WebResourceLoader::WillSendRequest(redirectRequest, redirectResponse));
-
     if (canUseCachedRedirect(request))
         m_cache->storeRedirect(request, redirectResponse, redirectRequest);
+
+    send(Messages::WebResourceLoader::WillSendRequest(redirectRequest, sanitizeRedirectResponseIfPossible(WTFMove(redirectResponse))));
+}
+
+ResourceResponse NetworkResourceLoader::sanitizeRedirectResponseIfPossible(ResourceResponse&& response)
+{
+    if (m_parameters.shouldRestrictHTTPResponseAccess)
+        response.sanitizeRedirectionHTTPHeaderFields();
+    return WTFMove(response);
 }
 
 void NetworkResourceLoader::continueWillSendRequest(ResourceRequest&& newRequest, bool isAllowedToAskUserForCredentials)
@@ -665,7 +672,7 @@ void NetworkResourceLoader::dispatchWillSendRequestForCacheEntry(std::unique_ptr
     LOG(NetworkCache, "(NetworkProcess) Executing cached redirect");
 
     ++m_redirectCount;
-    send(Messages::WebResourceLoader::WillSendRequest(*entry->redirectRequest(), entry->response()));
+    send(Messages::WebResourceLoader::WillSendRequest { *entry->redirectRequest(), sanitizeRedirectResponseIfPossible(ResourceResponse { entry->response() }) });
     m_isWaitingContinueWillSendRequestForCachedRedirect = true;
 }
 
index bf40cca..e9f2b06 100644 (file)
@@ -146,6 +146,8 @@ private:
     void logCookieInformation() const;
 #endif
 
+    WebCore::ResourceResponse sanitizeRedirectResponseIfPossible(WebCore::ResourceResponse&&);
+
     const NetworkResourceLoadParameters m_parameters;
 
     Ref<NetworkConnectionToWebProcess> m_connection;
index 9babe92..f86033e 100644 (file)
@@ -1213,3 +1213,10 @@ ResourceLoadStatisticsDebugMode:
   category: experimental
   webcoreBinding: RuntimeEnabledFeatures
 
+RestrictedHTTPResponseAccess:
+    type: bool
+    defaultValue: true
+    humanReadableName: "Restricted HTTP Response Access to Web Process"
+    humanReadableDescription: "Restricted HTTP Response Access to Web Process"
+    category: experimental
+    webcoreBinding: RuntimeEnabledFeatures
index 2438547..a4fcd2e 100644 (file)
@@ -1953,3 +1953,13 @@ bool WKPreferencesGetAllowCrossOriginSubresourcesToAskForCredentials(WKPreferenc
 {
     return toImpl(preferencesRef)->allowCrossOriginSubresourcesToAskForCredentials();
 }
+
+void WKPreferencesSetRestrictedHTTPResponseAccess(WKPreferencesRef preferencesRef, bool flag)
+{
+    toImpl(preferencesRef)->setRestrictedHTTPResponseAccess(flag);
+}
+
+bool WKPreferencesGetRestrictedHTTPResponseAccess(WKPreferencesRef preferencesRef)
+{
+    return toImpl(preferencesRef)->restrictedHTTPResponseAccess();
+}
index d31adb4..73c7c0b 100644 (file)
@@ -307,6 +307,10 @@ WK_EXPORT void WKPreferencesSetAllowMediaContentTypesRequiringHardwareSupportAsF
 WK_EXPORT bool WKPreferencesGetMediaCapabilitiesEnabled(WKPreferencesRef preferencesRef);
 WK_EXPORT void WKPreferencesSetMediaCapabilitiesEnabled(WKPreferencesRef preferencesRef, bool enabled);
 
+// Defaults to false.
+WK_EXPORT bool WKPreferencesGetRestrictedHTTPResponseAccess(WKPreferencesRef preferencesRef);
+WK_EXPORT void WKPreferencesSetRestrictedHTTPResponseAccess(WKPreferencesRef preferencesRef, bool allow);
+
 #ifdef __cplusplus
 }
 #endif
index 68cc0e6..26fb6b7 100644 (file)
@@ -59,6 +59,7 @@
 #include <WebCore/PlatformStrategies.h>
 #include <WebCore/ReferrerPolicy.h>
 #include <WebCore/ResourceLoader.h>
+#include <WebCore/RuntimeEnabledFeatures.h>
 #include <WebCore/SecurityOrigin.h>
 #include <WebCore/Settings.h>
 #include <WebCore/SubresourceLoader.h>
@@ -273,6 +274,9 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL
     loadParameters.maximumBufferingTime = maximumBufferingTime;
     loadParameters.derivedCachedDataTypesToRetrieve = resourceLoader.options().derivedCachedDataTypesToRetrieve;
 
+    // FIXME: We should also sanitize redirect response for navigations.
+    loadParameters.shouldRestrictHTTPResponseAccess = RuntimeEnabledFeatures::sharedFeatures().restrictedHTTPResponseAccess() && resourceLoader.options().mode != FetchOptions::Mode::Navigate;
+
     ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials);
 
     RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: Resource is being scheduled with the NetworkProcess (frame = %p, priority = %d, pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ")", resourceLoader.frame(), static_cast<int>(resourceLoader.request().priority()), loadParameters.webPageID, loadParameters.webFrameID, loadParameters.identifier);
@@ -427,6 +431,7 @@ void WebLoaderStrategy::loadResourceSynchronously(FrameLoader& frameLoader, unsi
     loadParameters.storedCredentialsPolicy = storedCredentialsPolicy;
     loadParameters.clientCredentialPolicy = clientCredentialPolicy;
     loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = shouldClearReferrerOnHTTPSToHTTPRedirect(webFrame ? webFrame->coreFrame() : nullptr);
+    loadParameters.shouldRestrictHTTPResponseAccess = RuntimeEnabledFeatures::sharedFeatures().restrictedHTTPResponseAccess();
 
     data.shrink(0);
 
@@ -465,6 +470,7 @@ void WebLoaderStrategy::startPingLoad(Frame& frame, ResourceRequest& request, co
     loadParameters.mode = options.mode;
     loadParameters.shouldFollowRedirects = options.redirect == FetchOptions::Redirect::Follow;
     loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = shouldClearReferrerOnHTTPSToHTTPRedirect(&frame);
+    loadParameters.shouldRestrictHTTPResponseAccess = RuntimeEnabledFeatures::sharedFeatures().restrictedHTTPResponseAccess();
     if (!document->shouldBypassMainWorldContentSecurityPolicy()) {
         if (auto * contentSecurityPolicy = document->contentSecurityPolicy())
             loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders();
@@ -521,6 +527,7 @@ void WebLoaderStrategy::preconnectTo(FrameLoader& frameLoader, const WebCore::UR
     parameters.sessionID = webPage ? webPage->sessionID() : PAL::SessionID::defaultSessionID();
     parameters.storedCredentialsPolicy = storedCredentialsPolicy;
     parameters.shouldPreconnectOnly = PreconnectOnly::Yes;
+    parameters.shouldRestrictHTTPResponseAccess = RuntimeEnabledFeatures::sharedFeatures().restrictedHTTPResponseAccess();
 
     WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::PreconnectTo(preconnectionIdentifier, WTFMove(parameters)), 0);
 }
index a94ac84..052f465 100644 (file)
@@ -1,3 +1,28 @@
+2018-04-03  Youenn Fablet  <youenn@apple.com>
+
+        NetworkResourceLoader does not need to expose all redirect response headers
+        https://bugs.webkit.org/show_bug.cgi?id=184114
+        <rdar://problem/39010557>
+
+        Reviewed by Ryosuke Niwa.
+
+        Add an option to dump the number of headers in a response.
+        This allows validating that filtering does happen or not.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+        (WTR::dumpResponseDescriptionSuitableForTestResult):
+        (WTR::InjectedBundlePage::responseHeaderCount):
+        (WTR::InjectedBundlePage::willSendRequestForFrame):
+        * WebKitTestRunner/InjectedBundle/InjectedBundlePage.h:
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        (WTR::TestRunner::dumpAllHTTPRedirectedResponseHeaders):
+        (WTR::TestRunner::shouldDumpAllHTTPRedirectedResponseHeaders const):
+        * WebKitTestRunner/InjectedBundle/cocoa/InjectedBundlePageCocoa.mm:
+        (WTR::InjectedBundlePage::responseHeaderCount):
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::resetPreferencesToConsistentValues):
+
 2018-04-03  Andy Estes  <aestes@apple.com>
 
         [Mac] Prioritize file promises over filenames during drag and drop
index 0e9f477..8935dae 100644 (file)
@@ -116,6 +116,8 @@ interface TestRunner {
     // Printing
     boolean isPageBoxVisible(long pageIndex);
 
+    void dumpAllHTTPRedirectedResponseHeaders();
+
     [PassContext] void setValueForUser(object element, DOMString value);
 
     // UserContent testing.
index 8edfb2f..3beda26 100644 (file)
@@ -499,7 +499,7 @@ static inline void dumpRequestDescriptionSuitableForTestResult(WKURLRequestRef r
     stringBuilder.append('>');
 }
 
-static inline void dumpResponseDescriptionSuitableForTestResult(WKURLResponseRef response, StringBuilder& stringBuilder)
+static inline void dumpResponseDescriptionSuitableForTestResult(WKURLResponseRef response, StringBuilder& stringBuilder, bool shouldDumpResponseHeaders = false)
 {
     WKRetainPtr<WKURLRef> url = adoptWK(WKURLResponseCopyURL(response));
     if (!url) {
@@ -510,9 +510,23 @@ static inline void dumpResponseDescriptionSuitableForTestResult(WKURLResponseRef
     stringBuilder.append(pathSuitableForTestResult(url.get()));
     stringBuilder.appendLiteral(", http status code ");
     stringBuilder.appendNumber(WKURLResponseHTTPStatusCode(response));
+
+    if (shouldDumpResponseHeaders) {
+        stringBuilder.appendLiteral(", ");
+        stringBuilder.appendNumber(InjectedBundlePage::responseHeaderCount(response));
+        stringBuilder.appendLiteral(" headers");
+    }
     stringBuilder.append('>');
 }
 
+#if !PLATFORM(COCOA)
+// FIXME: Implement this for non cocoa ports.
+uint64_t InjectedBundlePage::responseHeaderCount(WKURLResponseRef response)
+{
+    return 0;
+}
+#endif
+
 static inline void dumpErrorDescriptionSuitableForTestResult(WKErrorRef error, StringBuilder& stringBuilder)
 {
     WKRetainPtr<WKStringRef> errorDomain = adoptWK(WKErrorCopyDomain(error));
@@ -1133,7 +1147,7 @@ WKURLRequestRef InjectedBundlePage::willSendRequestForFrame(WKBundlePageRef page
         stringBuilder.appendLiteral(" - willSendRequest ");
         dumpRequestDescriptionSuitableForTestResult(request, stringBuilder);
         stringBuilder.appendLiteral(" redirectResponse ");
-        dumpResponseDescriptionSuitableForTestResult(response, stringBuilder);
+        dumpResponseDescriptionSuitableForTestResult(response, stringBuilder, injectedBundle.testRunner()->shouldDumpAllHTTPRedirectedResponseHeaders());
         stringBuilder.append('\n');
         injectedBundle.outputText(stringBuilder.toString());
     }
index 23b46e2..30e375c 100644 (file)
@@ -49,6 +49,8 @@ public:
 
     void dumpBackForwardList(WTF::StringBuilder&);
 
+    static uint64_t responseHeaderCount(WKURLResponseRef);
+
 private:
     // Loader Client
     static void didStartProvisionalLoadForFrame(WKBundlePageRef, WKBundleFrameRef, WKTypeRef*, const void*);
index b0a4661..7af8e65 100644 (file)
@@ -431,6 +431,9 @@ public:
 
     void installFakeHelvetica(JSStringRef configuration);
 
+    void dumpAllHTTPRedirectedResponseHeaders() { m_dumpAllHTTPRedirectedResponseHeaders = true; }
+    bool shouldDumpAllHTTPRedirectedResponseHeaders() const { return m_dumpAllHTTPRedirectedResponseHeaders; }
+
 private:
     TestRunner();
 
@@ -495,6 +498,8 @@ private:
     size_t m_userMediaPermissionRequestCount { 0 };
 
     PlatformTimerRef m_waitToDumpWatchdogTimer;
+
+    bool m_dumpAllHTTPRedirectedResponseHeaders { false };
 };
 
 } // namespace WTR
index d064461..6e2edbc 100644 (file)
@@ -53,4 +53,14 @@ String InjectedBundlePage::platformResponseMimeType(WKURLResponseRef response)
     return [nsURLResponse.get() MIMEType];
 }
 
+uint64_t InjectedBundlePage::responseHeaderCount(WKURLResponseRef response)
+{
+    RetainPtr<NSURLResponse> nsURLResponse = adoptNS(WKURLResponseCopyNSURLResponse(response));
+    if (![nsURLResponse isKindOfClass:[NSHTTPURLResponse class]])
+        return { };
+
+    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)nsURLResponse.get();
+    return [[httpResponse allHeaderFields] count];
+}
+
 } // namespace WTR
index 40005d5..948881c 100644 (file)
@@ -751,6 +751,8 @@ void TestController::resetPreferencesToConsistentValues(const TestOptions& optio
     WKPreferencesSetAccessibilityObjectModelEnabled(preferences, true);
     WKPreferencesSetMediaCapabilitiesEnabled(preferences, true);
 
+    WKPreferencesSetRestrictedHTTPResponseAccess(preferences, true);
+
     platformResetPreferencesToConsistentValues();
 }