Diff
Modified: trunk/LayoutTests/ChangeLog (220548 => 220549)
--- trunk/LayoutTests/ChangeLog 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/LayoutTests/ChangeLog 2017-08-10 21:51:15 UTC (rev 220549)
@@ -1,3 +1,18 @@
+2017-08-10 Chris Dumez <cdu...@apple.com>
+
+ [Beacon] Do connect-src CSP check on redirects as well
+ https://bugs.webkit.org/show_bug.cgi?id=175410
+ <rdar://problem/33815470>
+
+ Reviewed by Youenn Fablet.
+
+ Add layout test coverage.
+
+ * http/wpt/beacon/connect-src-beacon-redirect-allowed.sub-expected.txt: Added.
+ * http/wpt/beacon/connect-src-beacon-redirect-allowed.sub.html: Added.
+ * http/wpt/beacon/connect-src-beacon-redirect-blocked.sub-expected.txt: Added.
+ * http/wpt/beacon/connect-src-beacon-redirect-blocked.sub.html: Added.
+
2017-08-10 Jonathan Bedard <jbed...@apple.com>
Mark webgl/webgl-box-shadow.html and webgl/webgl-border.html as failing for ios-device.
Added: trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-allowed.sub-expected.txt (0 => 220549)
--- trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-allowed.sub-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-allowed.sub-expected.txt 2017-08-10 21:51:15 UTC (rev 220549)
@@ -0,0 +1,3 @@
+
+PASS Redirect is allowed by CSP
+
Added: trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-allowed.sub.html (0 => 220549)
--- trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-allowed.sub.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-allowed.sub.html 2017-08-10 21:51:15 UTC (rev 220549)
@@ -0,0 +1,53 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>SendBeacon CSP checking on redirect</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src=""
+ <script src=""
+ <script>
+var RESOURCES_DIR = "/WebKit/beacon/resources/";
+ let metaElement = document.createElement("meta");
+ metaElement.httpEquiv = "Content-Security-Policy";
+ metaElement.content = "connect-src 'self' " + get_host_info().HTTP_REMOTE_ORIGIN;
+ document.head.appendChild(metaElement);
+
+function pollResult(test, id) {
+ var checkUrl = RESOURCES_DIR + "beacon-preflight.py?cmd=get&id=" + id;
+
+ return new Promise(resolve => {
+ step_timeout(test.step_func(() => {
+ fetch(checkUrl).then(response => {
+ response.json().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function testCORSPreflightRedirectSuccess(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var target = encodeURIComponent(testBase + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id);
+
+ // 307 & 308 redirections are the only ones that maintain the POST method.
+ var testUrl = RESOURCES_DIR + "redirect.py?redirect_status=307&location=" + target;
+
+ promise_test(function(test) {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id) .then(result => {
+ assert_equals(result['preflight'], 0, "Did not receive preflight")
+ assert_equals(result['beacon'], 1, "Received beacon")
+ });
+ }, "Redirect is allowed by CSP");
+}
+
+testCORSPreflightRedirectSuccess("123");
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-blocked.sub-expected.txt (0 => 220549)
--- trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-blocked.sub-expected.txt (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-blocked.sub-expected.txt 2017-08-10 21:51:15 UTC (rev 220549)
@@ -0,0 +1,3 @@
+
+PASS Redirect is blocked by CSP
+
Added: trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-blocked.sub.html (0 => 220549)
--- trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-blocked.sub.html (rev 0)
+++ trunk/LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-blocked.sub.html 2017-08-10 21:51:15 UTC (rev 220549)
@@ -0,0 +1,50 @@
+<!doctype html>
+<html>
+ <head>
+ <meta http-equiv="Content-Security-Policy" content="connect-src 'self'">
+ <meta charset="utf-8">
+ <title>SendBeacon CSP blocking on redirect</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src=""
+ <script src=""
+ <script>
+var RESOURCES_DIR = "/WebKit/beacon/resources/";
+
+function pollResult(test, id) {
+ var checkUrl = RESOURCES_DIR + "beacon-preflight.py?cmd=get&id=" + id;
+
+ return new Promise(resolve => {
+ step_timeout(test.step_func(() => {
+ fetch(checkUrl).then(response => {
+ response.json().then(body => {
+ resolve(body);
+ });
+ });
+ }), 1000);
+ });
+}
+
+function testCORSPreflightRedirectSuccess(what) {
+ var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
+ var id = self.token();
+ var target = encodeURIComponent(testBase + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id);
+
+ // 307 & 308 redirections are the only ones that maintain the POST method.
+ var testUrl = RESOURCES_DIR + "redirect.py?redirect_status=307&location=" + target;
+
+ promise_test(function(test) {
+ assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
+ return pollResult(test, id) .then(result => {
+ assert_equals(result['preflight'], 0, "Did not receive preflight")
+ assert_equals(result['beacon'], 0, "Did not receive beacon")
+ });
+ }, "Redirect is blocked by CSP");
+}
+
+testCORSPreflightRedirectSuccess("123");
+ </script>
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (220548 => 220549)
--- trunk/Source/WebCore/ChangeLog 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebCore/ChangeLog 2017-08-10 21:51:15 UTC (rev 220549)
@@ -1,3 +1,38 @@
+2017-08-10 Chris Dumez <cdu...@apple.com>
+
+ [Beacon] Do connect-src CSP check on redirects as well
+ https://bugs.webkit.org/show_bug.cgi?id=175410
+ <rdar://problem/33815470>
+
+ Reviewed by Youenn Fablet.
+
+ Pass ContentSecurityPolicy object to createPingHandle so that we can send
+ enough data to the NetworkProcess so do CSP checks for Ping loads such
+ as Beacon. For the IPC, we serialize the ContentSecurityPolicy's response
+ headers. Those headers are now cached in ContentSecurityPolicy for
+ performance reasons. CSP headers are rarely updated in practice but
+ sendBeacon() may get called repeatedly for a given document.
+
+ Tests: http/wpt/beacon/connect-src-beacon-redirect-allowed.sub.html
+ http/wpt/beacon/connect-src-beacon-redirect-blocked.sub.html
+
+ * loader/LoaderStrategy.h:
+ * loader/PingLoader.cpp:
+ (WebCore::PingLoader::loadImage):
+ (WebCore::PingLoader::sendPing):
+ (WebCore::PingLoader::sendViolationReport):
+ (WebCore::PingLoader::startPingLoad):
+ * loader/PingLoader.h:
+ * loader/cache/CachedResource.cpp:
+ (WebCore::CachedResource::load):
+ * page/csp/ContentSecurityPolicy.cpp:
+ (WebCore::ContentSecurityPolicy::responseHeaders const):
+ (WebCore::ContentSecurityPolicy::didReceiveHeader):
+ * page/csp/ContentSecurityPolicy.h:
+ * page/csp/ContentSecurityPolicyResponseHeaders.h:
+ (WebCore::ContentSecurityPolicyResponseHeaders::encode const):
+ (WebCore::ContentSecurityPolicyResponseHeaders::decode):
+
2017-08-09 Yusuke Suzuki <utatane....@gmail.com>
[WTF] ThreadSpecific should not introduce additional indirection
Modified: trunk/Source/WebCore/loader/LoaderStrategy.h (220548 => 220549)
--- trunk/Source/WebCore/loader/LoaderStrategy.h 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebCore/loader/LoaderStrategy.h 2017-08-10 21:51:15 UTC (rev 220549)
@@ -34,6 +34,7 @@
namespace WebCore {
class CachedResource;
+class ContentSecurityPolicy;
class Frame;
class NetscapePlugInStreamLoader;
class NetscapePlugInStreamLoaderClient;
@@ -62,7 +63,7 @@
virtual void suspendPendingRequests() = 0;
virtual void resumePendingRequests() = 0;
- virtual void createPingHandle(NetworkingContext*, ResourceRequest&, Ref<SecurityOrigin>&& sourceOrigin, const FetchOptions&) = 0;
+ virtual void createPingHandle(NetworkingContext*, ResourceRequest&, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy*, const FetchOptions&) = 0;
virtual void storeDerivedDataToCache(const SHA1::Digest& bodyKey, const String& type, const String& partition, WebCore::SharedBuffer&) = 0;
Modified: trunk/Source/WebCore/loader/PingLoader.cpp (220548 => 220549)
--- trunk/Source/WebCore/loader/PingLoader.cpp 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebCore/loader/PingLoader.cpp 2017-08-10 21:51:15 UTC (rev 220549)
@@ -103,7 +103,7 @@
request.setHTTPReferrer(referrer);
frame.loader().addExtraFieldsToSubresourceRequest(request);
- startPingLoad(frame, request, document.securityOrigin(), ShouldFollowRedirects::Yes);
+ startPingLoad(frame, request, document, ShouldFollowRedirects::Yes);
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing
@@ -139,7 +139,7 @@
}
}
- startPingLoad(frame, request, sourceOrigin, ShouldFollowRedirects::Yes);
+ startPingLoad(frame, request, document, ShouldFollowRedirects::Yes);
}
void PingLoader::sendViolationReport(Frame& frame, const URL& reportURL, Ref<FormData>&& report, ViolationReportType reportType)
@@ -176,10 +176,10 @@
if (!referrer.isEmpty())
request.setHTTPReferrer(referrer);
- startPingLoad(frame, request, document.securityOrigin(), ShouldFollowRedirects::No);
+ startPingLoad(frame, request, document, ShouldFollowRedirects::No);
}
-void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, SecurityOrigin& sourceOrigin, ShouldFollowRedirects shouldFollowRedirects)
+void PingLoader::startPingLoad(Frame& frame, ResourceRequest& request, Document& document, ShouldFollowRedirects shouldFollowRedirects)
{
unsigned long identifier = frame.page()->progress().createUniqueIdentifier();
// FIXME: Why activeDocumentLoader? I would have expected documentLoader().
@@ -194,7 +194,8 @@
InspectorInstrumentation::continueAfterPingLoader(frame, identifier, frame.loader().activeDocumentLoader(), request, ResourceResponse());
- platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, sourceOrigin, options);
+ auto* contentSecurityPolicy = document.shouldBypassMainWorldContentSecurityPolicy() ? nullptr : document.contentSecurityPolicy();
+ platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, document.securityOrigin(), contentSecurityPolicy, options);
}
}
Modified: trunk/Source/WebCore/loader/PingLoader.h (220548 => 220549)
--- trunk/Source/WebCore/loader/PingLoader.h 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebCore/loader/PingLoader.h 2017-08-10 21:51:15 UTC (rev 220549)
@@ -37,11 +37,11 @@
namespace WebCore {
+class Document;
class FormData;
class Frame;
class URL;
class ResourceRequest;
-class SecurityOrigin;
enum class ViolationReportType {
ContentSecurityPolicy,
@@ -56,7 +56,7 @@
private:
enum class ShouldFollowRedirects { No, Yes };
- static void startPingLoad(Frame&, ResourceRequest&, SecurityOrigin& sourceOrigin, ShouldFollowRedirects);
+ static void startPingLoad(Frame&, ResourceRequest&, Document&, ShouldFollowRedirects);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (220548 => 220549)
--- trunk/Source/WebCore/loader/cache/CachedResource.cpp 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp 2017-08-10 21:51:15 UTC (rev 220549)
@@ -262,7 +262,10 @@
// FIXME: We should not special-case Beacon here.
if (m_options.keepAlive && type() == CachedResource::Beacon) {
ASSERT(m_origin);
- platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, *m_origin, m_options);
+ // Beacon is not exposed to workers so it is safe to rely on the document here.
+ auto* document = cachedResourceLoader.document();
+ auto* contentSecurityPolicy = document && !document->shouldBypassMainWorldContentSecurityPolicy() ? document->contentSecurityPolicy() : nullptr;
+ platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, *m_origin, contentSecurityPolicy, m_options);
return;
}
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp (220548 => 220549)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp 2017-08-10 21:51:15 UTC (rev 220549)
@@ -164,11 +164,14 @@
ContentSecurityPolicyResponseHeaders ContentSecurityPolicy::responseHeaders() const
{
- ContentSecurityPolicyResponseHeaders result;
- result.m_headers.reserveInitialCapacity(m_policies.size());
- for (auto& policy : m_policies)
- result.m_headers.uncheckedAppend({ policy->header(), policy->headerType() });
- return result;
+ if (!m_cachedResponseHeaders) {
+ ContentSecurityPolicyResponseHeaders result;
+ result.m_headers.reserveInitialCapacity(m_policies.size());
+ for (auto& policy : m_policies)
+ result.m_headers.uncheckedAppend({ policy->header(), policy->headerType() });
+ m_cachedResponseHeaders = WTFMove(result);
+ }
+ return *m_cachedResponseHeaders;
}
void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers, ReportParsingErrors reportParsingErrors)
@@ -188,6 +191,8 @@
m_hasAPIPolicy = true;
}
+ m_cachedResponseHeaders = std::nullopt;
+
// RFC2616, section 4.2 specifies that headers appearing multiple times can
// be combined with a comma. Walk the header string, and parse each comma
// separated chunk as a separate header.
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h (220548 => 220549)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h 2017-08-10 21:51:15 UTC (rev 220549)
@@ -65,8 +65,8 @@
WTF_MAKE_FAST_ALLOCATED;
public:
explicit ContentSecurityPolicy(ScriptExecutionContext&);
- explicit ContentSecurityPolicy(const SecurityOrigin&, const Frame* = nullptr);
- ~ContentSecurityPolicy();
+ WEBCORE_EXPORT explicit ContentSecurityPolicy(const SecurityOrigin&, const Frame* = nullptr);
+ WEBCORE_EXPORT ~ContentSecurityPolicy();
void copyStateFrom(const ContentSecurityPolicy*);
void copyUpgradeInsecureRequestStateFrom(const ContentSecurityPolicy&);
@@ -79,9 +79,9 @@
HTTPHeader,
Inherited,
};
- ContentSecurityPolicyResponseHeaders responseHeaders() const;
+ WEBCORE_EXPORT ContentSecurityPolicyResponseHeaders responseHeaders() const;
enum ReportParsingErrors { No, Yes };
- void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&, ReportParsingErrors = ReportParsingErrors::Yes);
+ WEBCORE_EXPORT void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&, ReportParsingErrors = ReportParsingErrors::Yes);
void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicy::PolicyFrom);
bool allowScriptWithNonce(const String& nonce, bool overrideContentSecurityPolicy = false) const;
@@ -107,7 +107,7 @@
bool allowChildFrameFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
bool allowChildContextFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
- bool allowConnectToSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
+ WEBCORE_EXPORT bool allowConnectToSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
bool allowFormAction(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
bool allowObjectFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
@@ -216,6 +216,7 @@
OptionSet<ContentSecurityPolicyHashAlgorithm> m_hashAlgorithmsForInlineScripts;
OptionSet<ContentSecurityPolicyHashAlgorithm> m_hashAlgorithmsForInlineStylesheets;
HashSet<RefPtr<SecurityOrigin>> m_insecureNavigationRequestsToUpgrade;
+ mutable std::optional<ContentSecurityPolicyResponseHeaders> m_cachedResponseHeaders;
};
}
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h (220548 => 220549)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h 2017-08-10 21:51:15 UTC (rev 220549)
@@ -42,16 +42,48 @@
class ContentSecurityPolicyResponseHeaders {
public:
+ ContentSecurityPolicyResponseHeaders() = default;
explicit ContentSecurityPolicyResponseHeaders(const ResourceResponse&);
ContentSecurityPolicyResponseHeaders isolatedCopy() const;
+ template <class Encoder> void encode(Encoder&) const;
+ template <class Decoder> static bool decode(Decoder&, ContentSecurityPolicyResponseHeaders&);
+
private:
friend class ContentSecurityPolicy;
- ContentSecurityPolicyResponseHeaders() = default;
-
Vector<std::pair<String, ContentSecurityPolicyHeaderType>> m_headers;
};
+template <class Encoder>
+void ContentSecurityPolicyResponseHeaders::encode(Encoder& encoder) const
+{
+ encoder << static_cast<uint64_t>(m_headers.size());
+ for (auto& pair : m_headers) {
+ encoder << pair.first;
+ encoder.encodeEnum(pair.second);
+ }
+}
+
+template <class Decoder>
+bool ContentSecurityPolicyResponseHeaders::decode(Decoder& decoder, ContentSecurityPolicyResponseHeaders& headers)
+{
+ uint64_t headersSize;
+ if (!decoder.decode(headersSize))
+ return false;
+ headers.m_headers.reserveCapacity(static_cast<size_t>(headersSize));
+ for (size_t i = 0; i < headersSize; ++i) {
+ String header;
+ if (!decoder.decode(header))
+ return false;
+ ContentSecurityPolicyHeaderType headerType;
+ if (!decoder.decodeEnum(headerType))
+ return false;
+ headers.m_headers.append(std::make_pair(header, headerType));
+ }
+
+ return true;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (220548 => 220549)
--- trunk/Source/WebKit/ChangeLog 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKit/ChangeLog 2017-08-10 21:51:15 UTC (rev 220549)
@@ -1,3 +1,32 @@
+2017-08-10 Chris Dumez <cdu...@apple.com>
+
+ [Beacon] Do connect-src CSP check on redirects as well
+ https://bugs.webkit.org/show_bug.cgi?id=175410
+ <rdar://problem/33815470>
+
+ Reviewed by Youenn Fablet.
+
+ Pass CSP Response headers to the NetworkProcess via NetworkResourceLoadParameters
+ when doing a PingLoad. This allows PingLoad to do CSP checks (in particular
+ connect-src ones) in case the ping load gets redirected. Those checks need to be
+ done on the NetworkProcess side at this point because there is no guarantee the
+ WebContent process is still around.
+
+ To do the CSP checks, PingLoad lazily reconstructs a ContentSecurityPolicy object
+ from the CSP response headers.
+
+ * NetworkProcess/NetworkResourceLoadParameters.cpp:
+ (WebKit::NetworkResourceLoadParameters::encode const):
+ (WebKit::NetworkResourceLoadParameters::decode):
+ * NetworkProcess/NetworkResourceLoadParameters.h:
+ * NetworkProcess/PingLoad.cpp:
+ (WebKit::PingLoad::willPerformHTTPRedirection):
+ (WebKit::PingLoad::contentSecurityPolicy):
+ * NetworkProcess/PingLoad.h:
+ * WebProcess/Network/WebLoaderStrategy.cpp:
+ (WebKit::WebLoaderStrategy::createPingHandle):
+ * WebProcess/Network/WebLoaderStrategy.h:
+
2017-08-10 Brian Burg <bb...@apple.com>
WKPreferences should conform to NSCopying
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp (220548 => 220549)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.cpp 2017-08-10 21:51:15 UTC (rev 220549)
@@ -87,6 +87,7 @@
if (sourceOrigin)
encoder << SecurityOriginData::fromSecurityOrigin(*sourceOrigin);
encoder.encodeEnum(mode);
+ encoder << cspResponseHeaders;
}
bool NetworkResourceLoadParameters::decode(IPC::Decoder& decoder, NetworkResourceLoadParameters& result)
@@ -163,6 +164,8 @@
}
if (!decoder.decodeEnum(result.mode))
return false;
+ if (!decoder.decode(result.cspResponseHeaders))
+ return false;
return true;
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h (220548 => 220549)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadParameters.h 2017-08-10 21:51:15 UTC (rev 220549)
@@ -28,6 +28,7 @@
#include "NetworkLoadParameters.h"
#include "SandboxExtension.h"
+#include <WebCore/ContentSecurityPolicyResponseHeaders.h>
#include <WebCore/FetchOptions.h>
#include <WebCore/ResourceHandle.h>
#include <WebCore/ResourceLoaderOptions.h>
@@ -57,6 +58,7 @@
Vector<String> derivedCachedDataTypesToRetrieve;
RefPtr<WebCore::SecurityOrigin> sourceOrigin;
WebCore::FetchOptions::Mode mode;
+ std::optional<WebCore::ContentSecurityPolicyResponseHeaders> cspResponseHeaders;
};
} // namespace WebKit
Modified: trunk/Source/WebKit/NetworkProcess/PingLoad.cpp (220548 => 220549)
--- trunk/Source/WebKit/NetworkProcess/PingLoad.cpp 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKit/NetworkProcess/PingLoad.cpp 2017-08-10 21:51:15 UTC (rev 220549)
@@ -32,6 +32,7 @@
#include "Logging.h"
#include "NetworkCORSPreflightChecker.h"
#include "SessionTracker.h"
+#include <WebCore/ContentSecurityPolicy.h>
#include <WebCore/CrossOriginAccessControl.h>
#define RELEASE_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(m_parameters.sessionID.isAlwaysOnLoggingAllowed(), Network, "%p - PingLoad::" fmt, this, ##__VA_ARGS__)
@@ -91,8 +92,17 @@
completionHandler({ });
return;
}
- // FIXME: Do CSP check.
+
+ if (auto* contentSecurityPolicy = this->contentSecurityPolicy()) {
+ if (!contentSecurityPolicy->allowConnectToSource(request.url(), redirectResponse.isNull() ? ContentSecurityPolicy::RedirectResponseReceived::No : ContentSecurityPolicy::RedirectResponseReceived::Yes)) {
+ RELEASE_LOG_IF_ALLOWED("willPerformHTTPRedirection - Redirect was blocked by CSP");
+ completionHandler({ });
+ return;
+ }
+ }
+
// FIXME: We should ensure the number of redirects does not exceed 20.
+
if (!needsCORSPreflight(request)) {
completionHandler(request);
return;
@@ -175,6 +185,15 @@
return !m_isSameOriginRequest || !securityOrigin().canRequest(request.url());
}
+ContentSecurityPolicy* PingLoad::contentSecurityPolicy() const
+{
+ if (!m_contentSecurityPolicy && m_parameters.cspResponseHeaders) {
+ m_contentSecurityPolicy = std::make_unique<ContentSecurityPolicy>(*m_parameters.sourceOrigin);
+ m_contentSecurityPolicy->didReceiveHeaders(*m_parameters.cspResponseHeaders, ContentSecurityPolicy::ReportParsingErrors::No);
+ }
+ return m_contentSecurityPolicy.get();
+}
+
void PingLoad::doCORSPreflight(const ResourceRequest& request)
{
RELEASE_LOG_IF_ALLOWED("doCORSPreflight");
Modified: trunk/Source/WebKit/NetworkProcess/PingLoad.h (220548 => 220549)
--- trunk/Source/WebKit/NetworkProcess/PingLoad.h 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKit/NetworkProcess/PingLoad.h 2017-08-10 21:51:15 UTC (rev 220549)
@@ -30,6 +30,10 @@
#include "NetworkDataTask.h"
#include "NetworkResourceLoadParameters.h"
+namespace WebCore {
+class ContentSecurityPolicy;
+}
+
namespace WebKit {
class NetworkCORSPreflightChecker;
@@ -41,6 +45,8 @@
private:
~PingLoad();
+ WebCore::ContentSecurityPolicy* contentSecurityPolicy() const;
+
void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&) final;
void didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler&&) final;
void didReceiveResponseNetworkSession(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) final;
@@ -64,6 +70,7 @@
RefPtr<WebCore::SecurityOrigin> m_origin;
bool m_isSameOriginRequest;
RedirectCompletionHandler m_redirectHandler;
+ mutable std::unique_ptr<WebCore::ContentSecurityPolicy> m_contentSecurityPolicy;
};
}
Modified: trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp (220548 => 220549)
--- trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp 2017-08-10 21:51:15 UTC (rev 220549)
@@ -46,6 +46,7 @@
#include "WebURLSchemeTaskProxy.h"
#include <WebCore/ApplicationCacheHost.h>
#include <WebCore/CachedResource.h>
+#include <WebCore/ContentSecurityPolicy.h>
#include <WebCore/DiagnosticLoggingClient.h>
#include <WebCore/DiagnosticLoggingKeys.h>
#include <WebCore/Document.h>
@@ -385,7 +386,7 @@
}
}
-void WebLoaderStrategy::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, Ref<SecurityOrigin>&& sourceOrigin, const FetchOptions& options)
+void WebLoaderStrategy::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, Ref<SecurityOrigin>&& sourceOrigin, ContentSecurityPolicy* contentSecurityPolicy, const FetchOptions& options)
{
// It's possible that call to createPingHandle might be made during initial empty Document creation before a NetworkingContext exists.
// It is not clear that we should send ping loads during that process anyways.
@@ -405,6 +406,8 @@
loadParameters.mode = options.mode;
loadParameters.shouldFollowRedirects = options.redirect == FetchOptions::Redirect::Follow;
loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = networkingContext->shouldClearReferrerOnHTTPSToHTTPRedirect();
+ if (contentSecurityPolicy)
+ loadParameters.cspResponseHeaders = contentSecurityPolicy->responseHeaders();
WebProcess::singleton().networkConnection().connection().send(Messages::NetworkConnectionToWebProcess::LoadPing(loadParameters), 0);
}
Modified: trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h (220548 => 220549)
--- trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h 2017-08-10 21:51:15 UTC (rev 220549)
@@ -41,29 +41,29 @@
class WebURLSchemeTaskProxy;
typedef uint64_t ResourceLoadIdentifier;
-class WebLoaderStrategy : public WebCore::LoaderStrategy {
+class WebLoaderStrategy final : public WebCore::LoaderStrategy {
WTF_MAKE_NONCOPYABLE(WebLoaderStrategy); WTF_MAKE_FAST_ALLOCATED;
public:
WebLoaderStrategy();
- ~WebLoaderStrategy() override;
+ ~WebLoaderStrategy() final;
- RefPtr<WebCore::SubresourceLoader> loadResource(WebCore::Frame&, WebCore::CachedResource&, const WebCore::ResourceRequest&, const WebCore::ResourceLoaderOptions&) override;
- void loadResourceSynchronously(WebCore::NetworkingContext*, unsigned long resourceLoadIdentifier, const WebCore::ResourceRequest&, WebCore::StoredCredentials, WebCore::ClientCredentialPolicy, WebCore::ResourceError&, WebCore::ResourceResponse&, Vector<char>& data) override;
+ RefPtr<WebCore::SubresourceLoader> loadResource(WebCore::Frame&, WebCore::CachedResource&, const WebCore::ResourceRequest&, const WebCore::ResourceLoaderOptions&) final;
+ void loadResourceSynchronously(WebCore::NetworkingContext*, unsigned long resourceLoadIdentifier, const WebCore::ResourceRequest&, WebCore::StoredCredentials, WebCore::ClientCredentialPolicy, WebCore::ResourceError&, WebCore::ResourceResponse&, Vector<char>& data) final;
- void remove(WebCore::ResourceLoader*) override;
- void setDefersLoading(WebCore::ResourceLoader*, bool) override;
- void crossOriginRedirectReceived(WebCore::ResourceLoader*, const WebCore::URL& redirectURL) override;
+ void remove(WebCore::ResourceLoader*) final;
+ void setDefersLoading(WebCore::ResourceLoader*, bool) final;
+ void crossOriginRedirectReceived(WebCore::ResourceLoader*, const WebCore::URL& redirectURL) final;
- void servePendingRequests(WebCore::ResourceLoadPriority minimumPriority) override;
+ void servePendingRequests(WebCore::ResourceLoadPriority minimumPriority) final;
- void suspendPendingRequests() override;
- void resumePendingRequests() override;
+ void suspendPendingRequests() final;
+ void resumePendingRequests() final;
- void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, const WebCore::FetchOptions&) override;
+ void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&) final;
- void storeDerivedDataToCache(const SHA1::Digest& bodyHash, const String& type, const String& partition, WebCore::SharedBuffer&) override;
+ void storeDerivedDataToCache(const SHA1::Digest& bodyHash, const String& type, const String& partition, WebCore::SharedBuffer&) final;
- void setCaptureExtraNetworkLoadMetricsEnabled(bool) override;
+ void setCaptureExtraNetworkLoadMetricsEnabled(bool) final;
WebResourceLoader* webResourceLoaderForIdentifier(ResourceLoadIdentifier identifier) const { return m_webResourceLoaders.get(identifier); }
RefPtr<WebCore::NetscapePlugInStreamLoader> schedulePluginStreamLoad(WebCore::Frame&, WebCore::NetscapePlugInStreamLoaderClient&, const WebCore::ResourceRequest&);
Modified: trunk/Source/WebKitLegacy/ChangeLog (220548 => 220549)
--- trunk/Source/WebKitLegacy/ChangeLog 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKitLegacy/ChangeLog 2017-08-10 21:51:15 UTC (rev 220549)
@@ -1,3 +1,18 @@
+2017-08-10 Chris Dumez <cdu...@apple.com>
+
+ [Beacon] Do connect-src CSP check on redirects as well
+ https://bugs.webkit.org/show_bug.cgi?id=175410
+ <rdar://problem/33815470>
+
+ Reviewed by Youenn Fablet.
+
+ Update createPingHandle() to take in ContentSecurityPolicy
+ object in but no behavior change for WK1.
+
+ * WebCoreSupport/WebResourceLoadScheduler.cpp:
+ (WebResourceLoadScheduler::createPingHandle):
+ * WebCoreSupport/WebResourceLoadScheduler.h:
+
2017-08-08 Chris Dumez <cdu...@apple.com>
[Beacon] Add support for CORS-preflighting for WK2 / NETWORK_SESSION
Modified: trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp (220548 => 220549)
--- trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.cpp 2017-08-10 21:51:15 UTC (rev 220549)
@@ -363,7 +363,7 @@
return m_requestsLoading.size() >= (webResourceLoadScheduler().isSerialLoadingEnabled() ? 1 : m_maxRequestsInFlight);
}
-void WebResourceLoadScheduler::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, Ref<SecurityOrigin>&&, const FetchOptions& options)
+void WebResourceLoadScheduler::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, Ref<SecurityOrigin>&&, WebCore::ContentSecurityPolicy*, const FetchOptions& options)
{
// PingHandle manages its own lifetime, deleting itself when its purpose has been fulfilled.
new PingHandle(networkingContext, request, options.credentials != FetchOptions::Credentials::Omit, PingHandle::UsesAsyncCallbacks::No, options.redirect == FetchOptions::Redirect::Follow);
Modified: trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h (220548 => 220549)
--- trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h 2017-08-10 21:19:51 UTC (rev 220548)
+++ trunk/Source/WebKitLegacy/WebCoreSupport/WebResourceLoadScheduler.h 2017-08-10 21:51:15 UTC (rev 220549)
@@ -59,7 +59,7 @@
void suspendPendingRequests() override;
void resumePendingRequests() override;
- void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, const WebCore::FetchOptions&) override;
+ void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, Ref<WebCore::SecurityOrigin>&& sourceOrigin, WebCore::ContentSecurityPolicy*, const WebCore::FetchOptions&) override;
void storeDerivedDataToCache(const SHA1::Digest&, const String&, const String&, WebCore::SharedBuffer&) override { }