REGRESSION (r231107): CSP report-only policies are ignored for beacon, importScripts...
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 May 2018 23:15:11 +0000 (23:15 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 May 2018 23:15:11 +0000 (23:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185789
<rdar://problem/40380175>

Reviewed by Andy Estes.

Source/WebCore:

Fixes an issue where CSP report-only policies were ignored for DocumentThreadableLoader and
PingLoad initiated loads as a result of moving CSP processing to NetworkProcess.

Have NetworkLoadChecker implement the ContentSecurityPolicyClient interface and support logging
console messages, sending CSP reports, and dispatching SecurityPolicyViolation events. To support
the latter we introduce a new WebPage message, EnqueueSecurityPolicyViolationEvent, to enqueue
a SecurityPolicyViolationEvent created from an event init dictionary on the document's event
dispatch queue.

Additionally, shorten the description for a ResourceError caused by CSP to "Blocked by Content Security Policy"
because the CSP code run in NetworkProcess can now log its more detailed error description to
Web Inspector.

Tests: http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html
       http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked.html
       http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php
       http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked.php

* WebCore.xcodeproj/project.pbxproj: Change SecurityPolicyViolationEvent.h from a project header to
a private header so that we can include it in WebKit code.
* dom/Document.cpp:
(WebCore::Document::enqueueSecurityPolicyViolationEvent): Added.
* dom/Document.h:

* dom/EventInit.h:
(WebCore::EventInit::encode const):
(WebCore::EventInit::decode
* dom/SecurityPolicyViolationEvent.h:
(WebCore::SecurityPolicyViolationEvent::Init::encode const):
(WebCore::SecurityPolicyViolationEvent::Init::decode):
Support encoding and decoding for the event.

* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::enqueueSecurityPolicyViolationEvent): Formerly named "dispatchSecurityPolicyViolationEvent".
(WebCore::DocumentLoader::dispatchSecurityPolicyViolationEvent): Deleted; renamed to "enqueueSecurityPolicyViolationEvent".
* loader/DocumentLoader.h:

* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::redirectReceived): While I am here, move the check for whether the loader
strategy took responsibility for performing security checks to be before we perform the CSP check to avoid doing
such CSP checks twice in the case that the loader strategy already did them.
(WebCore::DocumentThreadableLoader::didFail): Remove code that checked the CSP policy if the load failed. When
the loader strategy (NetworkProcess) is responsible for performing security checks then this code would never
be executed for a violation of a CSP report-only policy because the loader does not and should not fail the load
for a report-only violations. As the name implies, a report-only violation is only reported. That is, it is not
enforced such that the load is blocked; => fail the load.
(WebCore::DocumentThreadableLoader::reportContentSecurityPolicyError): Update the error description to more
accurately describe the error and be consistent with the error message used in NetworkProcess. This error
message is shown for a redirect blocked by CSP regardless of whether the redirect was to a same-origin or
cross-origin resource. I chose to make the error message more vague than necessary for simplicity because
the CSP code will log a more detailed message for this error than could ever be captured by error message
for the ResourceError. Also use ASCIILiteral to efficiently construct the String object for the error
message.

* page/csp/ContentSecurityPolicy.cpp:
(WebCore::ContentSecurityPolicy::reportViolation const): Build up a SecurityPolicyViolationEvent::Init and
pass that to the delegate to dispatch.
* page/csp/ContentSecurityPolicy.h: Export allowScriptFromSource() and allowChildContextFromSource() so that
we can call them from WebKit.
* page/csp/ContentSecurityPolicyClient.h: Update for renaming.
* platform/network/ResourceRequestBase.h: Define a new requester type to be able to differentiate a request
initiated by importScripts() from other requests. We use this to perform the appropriate CSP checks in NetworkProcess.
* workers/WorkerScriptLoader.cpp:
(WebCore::WorkerScriptLoader::loadSynchronously): Set the requester on the ResourceRequest to ResourceRequest::Requester::ImportScripts
so that we can differentiate this request from other requests. See remark for file ResourceRequestBase.h for
more details.

Source/WebKit:

Have NetworkLoadChecker implement the ContentSecurityPolicyClient interface and support logging
console messages, sending CSP reports, and dispatching SecurityPolicyViolation events.

* NetworkProcess/NetworkConnectionToWebProcess.cpp:
(WebKit::NetworkConnectionToWebProcess::loadPing):
* NetworkProcess/NetworkLoadChecker.cpp:
(WebKit::NetworkLoadChecker::NetworkLoadChecker): Modified to take a reference to the NetworkConnectionToWebProcess,
the web page ID, the web frame ID, and the resource load identifier. These details are necessary
in order to implement the ContentSecurityPolicyClient interface.
(WebKit::NetworkLoadChecker::isAllowedByContentSecurityPolicy): Added.
(WebKit::NetworkLoadChecker::continueCheckingRequest): Write in terms of isAllowedByContentSecurityPolicy().
(WebKit::NetworkLoadChecker::contentSecurityPolicy): Pass ourself as the client so that we receive
delegate callbacks.
(WebKit::NetworkLoadChecker::addConsoleMessage): Added.
(WebKit::NetworkLoadChecker::sendCSPViolationReport): Added.
(WebKit::NetworkLoadChecker::enqueueSecurityPolicyViolationEvent): Added.
* NetworkProcess/NetworkLoadChecker.h:
* NetworkProcess/NetworkResourceLoader.cpp:
(NetworkResourceLoader::enqueueSecurityPolicyViolationEvent): Added.
* NetworkProcess/NetworkResourceLoader.h:
* NetworkProcess/PingLoad.cpp:
(WebKit::PingLoad::PingLoad): Modified to take a reference to the NetworkConnectionToWebProcess and pass
this through to the NetworkLoadChecker along with the web page ID, web frame ID and resource load identifier.
* NetworkProcess/PingLoad.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::enqueueSecurityPolicyViolationEvent): Added.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in: Add message EnqueueSecurityPolicyViolationEvent.

LayoutTests:

Add some new tests and updated the expected results of other tests.

The tests connect-src-beacon-{allowed, blocked} are derived from the Blink test:
<https://chromium.googlesource.com/chromium/src/+/5c265c1a56a60533a1957589d33eabc201e2e8b6/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html>

* http/tests/quicklook/same-origin-xmlhttprequest-allowed-expected.txt: Update expected result. Note that these results are
a continuation of a regression caused by r231107. See <https://bugs.webkit.org/show_bug.cgi?id=185807> for more details.
* http/tests/security/contentSecurityPolicy/1.1/child-src/worker-redirect-blocked-expected.txt:
* http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html: Added.
* http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked.html: Added.
* http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked-expected.txt:
* http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked-expected.txt:
* http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php: Added.
* http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked.php: Added.
* http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt:
* http/tests/security/contentSecurityPolicy/worker-csp-blocks-xhr-redirect-cross-origin-expected.txt:
* http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt:
* http/wpt/beacon/connect-src-beacon-redirect-blocked.sub-expected.txt:
* platform/mac-wk1/TestExpectations: Skip the beacon tests because we do not support beacon in WebKit1.
* platform/mac-wk1/http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked-expected.txt:
* platform/mac-wk1/http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked-expected.txt:
* platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt: Added.
* platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt: Added.
* platform/win/TestExpectations: Skip the beacon tests because we do not support beacon in WebKit1.
* platform/win/http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked-expected.txt:
* platform/win/http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked-expected.txt:
* platform/win/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt: Added.
* platform/win/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt: Added.

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

52 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/quicklook/same-origin-xmlhttprequest-allowed-expected.txt
LayoutTests/http/tests/security/contentSecurityPolicy/1.1/child-src/worker-redirect-blocked-expected.txt
LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked.html [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked-expected.txt
LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked-expected.txt
LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked.php [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt
LayoutTests/http/tests/security/contentSecurityPolicy/worker-csp-blocks-xhr-redirect-cross-origin-expected.txt
LayoutTests/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt
LayoutTests/http/wpt/beacon/connect-src-beacon-redirect-blocked.sub-expected.txt
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked-expected.txt
LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked-expected.txt
LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt [new file with mode: 0644]
LayoutTests/platform/win/TestExpectations
LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked-expected.txt
LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked-expected.txt
LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt [new file with mode: 0644]
LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/EventInit.h
Source/WebCore/dom/SecurityPolicyViolationEvent.h
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/DocumentLoader.h
Source/WebCore/loader/DocumentThreadableLoader.cpp
Source/WebCore/page/csp/ContentSecurityPolicy.cpp
Source/WebCore/page/csp/ContentSecurityPolicy.h
Source/WebCore/page/csp/ContentSecurityPolicyClient.h
Source/WebCore/platform/network/ResourceRequestBase.h
Source/WebCore/workers/WorkerScriptLoader.cpp
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
Source/WebKit/NetworkProcess/NetworkLoadChecker.cpp
Source/WebKit/NetworkProcess/NetworkLoadChecker.h
Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
Source/WebKit/NetworkProcess/NetworkResourceLoader.h
Source/WebKit/NetworkProcess/PingLoad.cpp
Source/WebKit/NetworkProcess/PingLoad.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in

index 441dcd8..4a51d66 100644 (file)
@@ -1,3 +1,44 @@
+2018-05-21  Daniel Bates  <dabates@apple.com>
+
+        REGRESSION (r231107): CSP report-only policies are ignored for beacon, importScripts, fetch(), EventSource, and XHR
+        https://bugs.webkit.org/show_bug.cgi?id=185789
+        <rdar://problem/40380175>
+
+        Reviewed by Andy Estes.
+
+        Add some new tests and updated the expected results of other tests.
+
+        The tests connect-src-beacon-{allowed, blocked} are derived from the Blink test:
+        <https://chromium.googlesource.com/chromium/src/+/5c265c1a56a60533a1957589d33eabc201e2e8b6/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html>
+
+        * http/tests/quicklook/same-origin-xmlhttprequest-allowed-expected.txt: Update expected result. Note that these results are
+        a continuation of a regression caused by r231107. See <https://bugs.webkit.org/show_bug.cgi?id=185807> for more details.
+        * http/tests/security/contentSecurityPolicy/1.1/child-src/worker-redirect-blocked-expected.txt:
+        * http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html: Added.
+        * http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked.html: Added.
+        * http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked-expected.txt:
+        * http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked-expected.txt:
+        * http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php: Added.
+        * http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked.php: Added.
+        * http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt:
+        * http/tests/security/contentSecurityPolicy/worker-csp-blocks-xhr-redirect-cross-origin-expected.txt:
+        * http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt:
+        * http/wpt/beacon/connect-src-beacon-redirect-blocked.sub-expected.txt:
+        * platform/mac-wk1/TestExpectations: Skip the beacon tests because we do not support beacon in WebKit1.
+        * platform/mac-wk1/http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked-expected.txt:
+        * platform/mac-wk1/http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked-expected.txt:
+        * platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt: Added.
+        * platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt: Added.
+        * platform/win/TestExpectations: Skip the beacon tests because we do not support beacon in WebKit1.
+        * platform/win/http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked-expected.txt:
+        * platform/win/http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked-expected.txt:
+        * platform/win/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt: Added.
+        * platform/win/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt: Added.
+
 2018-05-21  Chris Dumez  <cdumez@apple.com>
 
         File's structured serialization should serialize lastModified attribute
index 3514f2a..ead1bcd 100644 (file)
@@ -1,4 +1,5 @@
-CONSOLE MESSAGE: Blocked by Content Security Policy
+CONSOLE MESSAGE: Refused to connect to about: because it appears in neither the connect-src directive nor the default-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
 CONSOLE MESSAGE: XMLHttpRequest cannot load about: due to access control checks.
 CONSOLE MESSAGE: line 1: PASS: XMLHttpRequest allowed
 
index 9aba0fc..63fe700 100644 (file)
@@ -1,8 +1,6 @@
-CONSOLE MESSAGE: Unsafe attempt to load URL http://localhost:8000/security/contentSecurityPolicy/resources/alert-fail.js from origin http://127.0.0.1:8000. Domains, protocols and ports must match.
-
 CONSOLE MESSAGE: Refused to load http://localhost:8000/security/contentSecurityPolicy/resources/alert-fail.js because it does not appear in the child-src directive of the Content Security Policy.
-CONSOLE MESSAGE: Cross-origin redirection denied by Content Security Policy.
-CONSOLE MESSAGE: Cannot load http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php?url=http://localhost:8000/security/contentSecurityPolicy/resources/alert-fail.js due to access control checks.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
+CONSOLE MESSAGE: Cannot load http://localhost:8000/security/contentSecurityPolicy/resources/alert-fail.js due to access control checks.
 This tests that the Content Security Policy of the page blocks loading a Web Worker's script from a different origin through a redirect.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed-expected.txt
new file mode 100644 (file)
index 0000000..0533f45
--- /dev/null
@@ -0,0 +1,2 @@
+Pass
+
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html b/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html
new file mode 100644 (file)
index 0000000..eca3056
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="connect-src http://127.0.0.1:8000">
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+</head>
+<body>
+<pre id="console"></pre>
+<script>
+function log(msg)
+{
+    document.getElementById("console").appendChild(document.createTextNode(msg + "\n"));
+}
+
+try {
+    navigator.sendBeacon("http://127.0.0.1:8000/security/contentSecurityPolicy/resources/echo-report.php");
+    log("Pass");
+} catch(e) {
+    log("Fail");
+}
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked-expected.txt
new file mode 100644 (file)
index 0000000..38caa41
--- /dev/null
@@ -0,0 +1,3 @@
+CONSOLE MESSAGE: Refused to connect to http://localhost:8000/security/contentSecurityPolicy/resources/echo-report.php because it does not appear in the connect-src directive of the Content Security Policy.
+Pass
+
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked.html b/LayoutTests/http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked.html
new file mode 100644 (file)
index 0000000..1eadc69
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="connect-src 'none'">
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+</head>
+<body>
+<pre id="console"></pre>
+<script>
+function log(msg)
+{
+    document.getElementById("console").appendChild(document.createTextNode(msg + "\n"));
+}
+
+try {
+    navigator.sendBeacon("http://localhost:8000/security/contentSecurityPolicy/resources/echo-report.php");
+    log("Pass");
+} catch(e) {
+    log("Fail");
+}
+</script>
+</body>
+</html>
index 4e4961e..564743a 100644 (file)
@@ -1,7 +1,6 @@
-CONSOLE MESSAGE: Blocked http://localhost:8000/eventsource/resources/simple-event-stream.asis by Content Security Policy
 CONSOLE MESSAGE: Refused to connect to http://localhost:8000/eventsource/resources/simple-event-stream.asis because it does not appear in the connect-src directive of the Content Security Policy.
-CONSOLE MESSAGE: Cross-origin redirection denied by Content Security Policy.
-CONSOLE MESSAGE: EventSource cannot load http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php?url=http://localhost:8000/eventsource/resources/simple-event-stream.asis due to access control checks.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
+CONSOLE MESSAGE: EventSource cannot load http://localhost:8000/eventsource/resources/simple-event-stream.asis due to access control checks.
 PASS EventSource() did not follow the disallowed redirect.
 PASS successfullyParsed is true
 
index 87e8d03..a868de6 100644 (file)
@@ -1,7 +1,6 @@
-CONSOLE MESSAGE: Blocked http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl by Content Security Policy
 CONSOLE MESSAGE: Refused to connect to http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl because it does not appear in the connect-src directive of the Content Security Policy.
-CONSOLE MESSAGE: Cross-origin redirection denied by Content Security Policy.
-CONSOLE MESSAGE: XMLHttpRequest cannot load http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php?url=http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl due to access control checks.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
+CONSOLE MESSAGE: XMLHttpRequest cannot load http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl due to access control checks.
 PASS XMLHttpRequest.send() did not follow the disallowed redirect.
 PASS successfullyParsed is true
 
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked-expected.txt
new file mode 100644 (file)
index 0000000..2eec6fc
--- /dev/null
@@ -0,0 +1,3 @@
+CONSOLE MESSAGE: The Content Security Policy 'connect-src http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.
+Pass
+
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php b/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php
new file mode 100644 (file)
index 0000000..b43bcc8
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+    header("Content-Security-Policy-Report-Only: connect-src http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php");
+?>
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+</head>
+<body>
+<pre id="console"></pre>
+<script>
+function log(msg)
+{
+    document.getElementById("console").appendChild(document.createTextNode(msg + "\n"));
+}
+
+try {
+    navigator.sendBeacon("http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php?url=http://localhost:8000/security/contentSecurityPolicy/resources/echo-report.php");
+    log("Pass");
+} catch(e) {
+    log("Fail");
+}
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked-expected.txt
new file mode 100644 (file)
index 0000000..63192fa
--- /dev/null
@@ -0,0 +1,7 @@
+CONSOLE MESSAGE: The Content Security Policy 'connect-src http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.
+CONSOLE MESSAGE: [Report Only] Refused to connect to http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl because it does not appear in the connect-src directive of the Content Security Policy.
+PASS XMLHttpRequest.send() did follow the redirect.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked.php b/LayoutTests/http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked.php
new file mode 100644 (file)
index 0000000..532411e
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+    header("Content-Security-Policy-Report-Only: connect-src http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php");
+?>
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+    <script>
+        window.jsTestIsAsync = true;
+        function log(msg) {
+            document.getElementById("console").appendChild(document.createTextNode(msg + "\n"));
+        }
+
+        var xhr = new XMLHttpRequest;
+        try {
+            // Redirect to a different host, because as of CSP2 paths are ignored when matching after a redirect.
+            xhr.open("GET", "resources/redir.php?url=http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl", true);
+        } catch(e) {
+            testFailed("XMLHttpRequest.open() should not throw an exception.");
+        }
+
+        xhr.onload = function () {
+            testPassed("XMLHttpRequest.send() did follow the redirect.");
+            finishJSTest();
+        };
+
+        xhr.onerror = function () {
+            testFailed("XMLHttpRequest.send() did not follow the redirect.");
+            finishJSTest();
+        };
+
+        xhr.send();
+    </script>
+</script>
+<script src="/js-test-resources/js-test-post.js"></script>
+</body>
+</html>
index 35ffae8..e3a5cd5 100644 (file)
@@ -1,3 +1,5 @@
+CONSOLE MESSAGE: Refused to load http://localhost:8000/security/contentSecurityPolicy/resources/script-set-value.js because it does not appear in the script-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
 This tests that the Content Security Policy of the parent origin (this page) blocks a Web Worker from importing a script from a different origin, not listed in script-src, through a redirect.
 
-PASS threw exception NetworkError: Cross-origin redirection denied by Content Security Policy..
+PASS threw exception NetworkError: Blocked by Content Security Policy..
index 0423a3e..3881f91 100644 (file)
@@ -1,4 +1,5 @@
-CONSOLE MESSAGE: Blocked http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow.cgi by Content Security Policy
+CONSOLE MESSAGE: Refused to connect to http://localhost:8000/xmlhttprequest/resources/access-control-basic-allow.cgi because it does not appear in the connect-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
 This tests an XHR request made from a worker is blocked if it redirects to a cross-origin resource that is not listed as a connect-src in the CSP of the worker.
 
 PASS threw exception NetworkError:  A network error occurred..
index 9154893..29fc436 100644 (file)
@@ -1,3 +1,5 @@
+CONSOLE MESSAGE: Refused to load http://localhost:8000/security/contentSecurityPolicy/resources/script-set-value.js because it does not appear in the script-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
 This tests a Web Worker with Content Security Policy "script-src 'self'" blocks the import of a script from a different origin through a redirect.
 
-PASS threw exception NetworkError: Cross-origin redirection denied by Content Security Policy..
+PASS threw exception NetworkError: Blocked by Content Security Policy..
index a2b7a6f..fc75d81 100644 (file)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: Beacon API cannot load http://127.0.0.1:8800/WebKit/beacon/resources/beacon-preflight.py?allowCors=1&cmd=put&id=2539e883-7dfb-4dde-a227-a41c670d5fe1&redirect_status=307&location=http%3A%2F%2F127.0.0.1%3A8800%2FWebKit%2Fbeacon%2Fresources%2Fbeacon-preflight.py%3FallowCors%3D1%26cmd%3Dput%26id%3D2539e883-7dfb-4dde-a227-a41c670d5fe1&count=1. Blocked http://127.0.0.1:8800/WebKit/beacon/resources/beacon-preflight.py?allowCors=1&cmd=put&id=2539e883-7dfb-4dde-a227-a41c670d5fe1&redirect_status=307&location=http%3A%2F%2F127.0.0.1%3A8800%2FWebKit%2Fbeacon%2Fresources%2Fbeacon-preflight.py%3FallowCors%3D1%26cmd%3Dput%26id%3D2539e883-7dfb-4dde-a227-a41c670d5fe1&count=1 by Content Security Policy
+CONSOLE MESSAGE: Beacon API cannot load http://127.0.0.1:8800/WebKit/beacon/resources/beacon-preflight.py?allowCors=1&cmd=put&id=2539e883-7dfb-4dde-a227-a41c670d5fe1&redirect_status=307&location=http%3A%2F%2F127.0.0.1%3A8800%2FWebKit%2Fbeacon%2Fresources%2Fbeacon-preflight.py%3FallowCors%3D1%26cmd%3Dput%26id%3D2539e883-7dfb-4dde-a227-a41c670d5fe1&count=1. Blocked by Content Security Policy.
 
 PASS Redirect is blocked by CSP 
 
index 2cb88b3..4fca1c6 100644 (file)
@@ -432,6 +432,9 @@ http/tests/inspector/network/beacon-type.html [ Skip ]
 http/wpt/beacon/ [ Skip ]
 imported/blink/fast/beacon/ [ Skip ]
 imported/w3c/web-platform-tests/beacon/ [ Skip ]
+http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html [ Skip ]
+http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked.html [ Skip ]
+http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php [ Skip ]
 
 # This was a WK2-only fix.
 http/tests/css/filters-on-iframes.html [ Skip ]
index 49f2671..31c19ec 100644 (file)
@@ -1,5 +1,5 @@
 CONSOLE MESSAGE: Refused to connect to http://localhost:8000/eventsource/resources/simple-event-stream.asis because it does not appear in the connect-src directive of the Content Security Policy.
-CONSOLE MESSAGE: Cross-origin redirection denied by Content Security Policy.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
 CONSOLE MESSAGE: EventSource cannot load http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php?url=http://localhost:8000/eventsource/resources/simple-event-stream.asis due to access control checks.
 PASS EventSource() did not follow the disallowed redirect.
 PASS successfullyParsed is true
index 8ecc3cb..41640ef 100644 (file)
@@ -1,5 +1,5 @@
 CONSOLE MESSAGE: Refused to connect to http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl because it does not appear in the connect-src directive of the Content Security Policy.
-CONSOLE MESSAGE: Cross-origin redirection denied by Content Security Policy.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
 CONSOLE MESSAGE: XMLHttpRequest cannot load http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php?url=http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl due to access control checks.
 PASS XMLHttpRequest.send() did not follow the disallowed redirect.
 PASS successfullyParsed is true
diff --git a/LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt b/LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt
new file mode 100644 (file)
index 0000000..37fcda4
--- /dev/null
@@ -0,0 +1,3 @@
+This tests that the Content Security Policy of the parent origin (this page) blocks a Web Worker from importing a script from a different origin, not listed in script-src, through a redirect.
+
+PASS threw exception NetworkError: Blocked by Content Security Policy..
diff --git a/LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt b/LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt
new file mode 100644 (file)
index 0000000..76467a2
--- /dev/null
@@ -0,0 +1,3 @@
+This tests a Web Worker with Content Security Policy "script-src 'self'" blocks the import of a script from a different origin through a redirect.
+
+PASS threw exception NetworkError: Blocked by Content Security Policy..
index 681edfa..a1d828e 100644 (file)
@@ -3775,6 +3775,9 @@ http/tests/inspector/network/beacon-type.html [ Skip ]
 http/wpt/beacon/ [ Skip ]
 imported/blink/fast/beacon/ [ Skip ]
 imported/w3c/web-platform-tests/beacon/ [ Skip ]
+http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html [ Skip ]
+http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked.html [ Skip ]
+http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php [ Skip ]
 
 # Async image tests are currently failing on Windows.
 webkit.org/b/174653 fast/images/async-image-background-image-repeated.html [ Timeout ]
index 49f2671..31c19ec 100644 (file)
@@ -1,5 +1,5 @@
 CONSOLE MESSAGE: Refused to connect to http://localhost:8000/eventsource/resources/simple-event-stream.asis because it does not appear in the connect-src directive of the Content Security Policy.
-CONSOLE MESSAGE: Cross-origin redirection denied by Content Security Policy.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
 CONSOLE MESSAGE: EventSource cannot load http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php?url=http://localhost:8000/eventsource/resources/simple-event-stream.asis due to access control checks.
 PASS EventSource() did not follow the disallowed redirect.
 PASS successfullyParsed is true
index 8ecc3cb..41640ef 100644 (file)
@@ -1,5 +1,5 @@
 CONSOLE MESSAGE: Refused to connect to http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl because it does not appear in the connect-src directive of the Content Security Policy.
-CONSOLE MESSAGE: Cross-origin redirection denied by Content Security Policy.
+CONSOLE MESSAGE: Blocked by Content Security Policy.
 CONSOLE MESSAGE: XMLHttpRequest cannot load http://127.0.0.1:8000/security/contentSecurityPolicy/resources/redir.php?url=http://localhost:8000/security/contentSecurityPolicy/resources/xhr-redirect-not-allowed.pl due to access control checks.
 PASS XMLHttpRequest.send() did not follow the disallowed redirect.
 PASS successfullyParsed is true
diff --git a/LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt b/LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-importScripts-redirect-cross-origin-blocked-expected.txt
new file mode 100644 (file)
index 0000000..37fcda4
--- /dev/null
@@ -0,0 +1,3 @@
+This tests that the Content Security Policy of the parent origin (this page) blocks a Web Worker from importing a script from a different origin, not listed in script-src, through a redirect.
+
+PASS threw exception NetworkError: Blocked by Content Security Policy..
diff --git a/LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt b/LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/worker-csp-importScripts-redirect-cross-origin-blocked-expected.txt
new file mode 100644 (file)
index 0000000..76467a2
--- /dev/null
@@ -0,0 +1,3 @@
+This tests a Web Worker with Content Security Policy "script-src 'self'" blocks the import of a script from a different origin through a redirect.
+
+PASS threw exception NetworkError: Blocked by Content Security Policy..
index f514aaa..7979276 100644 (file)
@@ -1,3 +1,78 @@
+2018-05-21  Daniel Bates  <dabates@apple.com>
+
+        REGRESSION (r231107): CSP report-only policies are ignored for beacon, importScripts, fetch(), EventSource, and XHR
+        https://bugs.webkit.org/show_bug.cgi?id=185789
+        <rdar://problem/40380175>
+
+        Reviewed by Andy Estes.
+
+        Fixes an issue where CSP report-only policies were ignored for DocumentThreadableLoader and
+        PingLoad initiated loads as a result of moving CSP processing to NetworkProcess.
+
+        Have NetworkLoadChecker implement the ContentSecurityPolicyClient interface and support logging
+        console messages, sending CSP reports, and dispatching SecurityPolicyViolation events. To support
+        the latter we introduce a new WebPage message, EnqueueSecurityPolicyViolationEvent, to enqueue
+        a SecurityPolicyViolationEvent created from an event init dictionary on the document's event
+        dispatch queue.
+
+        Additionally, shorten the description for a ResourceError caused by CSP to "Blocked by Content Security Policy"
+        because the CSP code run in NetworkProcess can now log its more detailed error description to
+        Web Inspector.
+
+        Tests: http/tests/security/contentSecurityPolicy/connect-src-beacon-allowed.html
+               http/tests/security/contentSecurityPolicy/connect-src-beacon-blocked.html
+               http/tests/security/contentSecurityPolicy/report-only-connect-src-beacon-redirect-blocked.php
+               http/tests/security/contentSecurityPolicy/report-only-connect-src-xmlhttprequest-redirect-to-blocked.php
+
+        * WebCore.xcodeproj/project.pbxproj: Change SecurityPolicyViolationEvent.h from a project header to
+        a private header so that we can include it in WebKit code.
+        * dom/Document.cpp:
+        (WebCore::Document::enqueueSecurityPolicyViolationEvent): Added.
+        * dom/Document.h:
+
+        * dom/EventInit.h:
+        (WebCore::EventInit::encode const):
+        (WebCore::EventInit::decode
+        * dom/SecurityPolicyViolationEvent.h:
+        (WebCore::SecurityPolicyViolationEvent::Init::encode const):
+        (WebCore::SecurityPolicyViolationEvent::Init::decode):
+        Support encoding and decoding for the event.
+
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::enqueueSecurityPolicyViolationEvent): Formerly named "dispatchSecurityPolicyViolationEvent".
+        (WebCore::DocumentLoader::dispatchSecurityPolicyViolationEvent): Deleted; renamed to "enqueueSecurityPolicyViolationEvent".
+        * loader/DocumentLoader.h:
+
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::redirectReceived): While I am here, move the check for whether the loader
+        strategy took responsibility for performing security checks to be before we perform the CSP check to avoid doing
+        such CSP checks twice in the case that the loader strategy already did them.
+        (WebCore::DocumentThreadableLoader::didFail): Remove code that checked the CSP policy if the load failed. When
+        the loader strategy (NetworkProcess) is responsible for performing security checks then this code would never
+        be executed for a violation of a CSP report-only policy because the loader does not and should not fail the load
+        for a report-only violations. As the name implies, a report-only violation is only reported. That is, it is not
+        enforced such that the load is blocked; => fail the load.
+        (WebCore::DocumentThreadableLoader::reportContentSecurityPolicyError): Update the error description to more
+        accurately describe the error and be consistent with the error message used in NetworkProcess. This error
+        message is shown for a redirect blocked by CSP regardless of whether the redirect was to a same-origin or
+        cross-origin resource. I chose to make the error message more vague than necessary for simplicity because
+        the CSP code will log a more detailed message for this error than could ever be captured by error message
+        for the ResourceError. Also use ASCIILiteral to efficiently construct the String object for the error
+        message.
+
+        * page/csp/ContentSecurityPolicy.cpp:
+        (WebCore::ContentSecurityPolicy::reportViolation const): Build up a SecurityPolicyViolationEvent::Init and
+        pass that to the delegate to dispatch.
+        * page/csp/ContentSecurityPolicy.h: Export allowScriptFromSource() and allowChildContextFromSource() so that
+        we can call them from WebKit.
+        * page/csp/ContentSecurityPolicyClient.h: Update for renaming.
+        * platform/network/ResourceRequestBase.h: Define a new requester type to be able to differentiate a request
+        initiated by importScripts() from other requests. We use this to perform the appropriate CSP checks in NetworkProcess.
+        * workers/WorkerScriptLoader.cpp:
+        (WebCore::WorkerScriptLoader::loadSynchronously): Set the requester on the ResourceRequest to ResourceRequest::Requester::ImportScripts
+        so that we can differentiate this request from other requests. See remark for file ResourceRequestBase.h for
+        more details.
+
 2018-05-21  Chris Dumez  <cdumez@apple.com>
 
         File's structured serialization should serialize lastModified attribute
index b5104d1..a2795c5 100644 (file)
                2D50A4B81CE10E0000198049 /* AttachmentPlaceholder@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2D50A4B61CE10E0000198049 /* AttachmentPlaceholder@2x.png */; };
                2D5646B01B8F8493003C4994 /* DictionaryPopupInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5646AF1B8F8493003C4994 /* DictionaryPopupInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
                2D5A5931152525D00036EE51 /* ImageOrientation.h in Headers */ = {isa = PBXBuildFile; fileRef = A8748D6612CC3763001FBA41 /* ImageOrientation.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5BC42516F882BE007048D0 /* SecurityPolicyViolationEvent.h */; };
+               2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5BC42516F882BE007048D0 /* SecurityPolicyViolationEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
                2D5C9D0019C7B52E00B3C5C1 /* PageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5C9CFC19C7B52E00B3C5C1 /* PageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; };
                2D5C9D0219C7B52E00B3C5C1 /* PageOverlayController.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D5C9CFE19C7B52E00B3C5C1 /* PageOverlayController.h */; settings = {ATTRIBUTES = (Private, ); }; };
                2D6F3E901C1ECB270061DBD4 /* MockPageOverlay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D6F3E8A1C1ECB1C0061DBD4 /* MockPageOverlay.cpp */; };
index fd232df..ca87947 100644 (file)
@@ -5942,6 +5942,11 @@ void Document::dispatchPageshowEvent(PageshowEventPersistence persisted)
     dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, persisted), this);
 }
 
+void Document::enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&& eventInit)
+{
+    enqueueDocumentEvent(SecurityPolicyViolationEvent::create(eventNames().securitypolicyviolationEvent, WTFMove(eventInit), Event::IsTrusted::Yes));
+}
+
 void Document::enqueueHashchangeEvent(const String& oldURL, const String& newURL)
 {
     enqueueWindowEvent(HashChangeEvent::create(oldURL, newURL));
index b363358..93b1e53 100644 (file)
@@ -45,6 +45,7 @@
 #include "Region.h"
 #include "RenderPtr.h"
 #include "ScriptExecutionContext.h"
+#include "SecurityPolicyViolationEvent.h"
 #include "StringWithDirection.h"
 #include "StyleColor.h"
 #include "Supplementable.h"
@@ -1114,6 +1115,7 @@ public:
     void enqueueDocumentEvent(Ref<Event>&&);
     void enqueueOverflowEvent(Ref<Event>&&);
     void dispatchPageshowEvent(PageshowEventPersistence);
+    WEBCORE_EXPORT void enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&&);
     void enqueueHashchangeEvent(const String& oldURL, const String& newURL);
     void dispatchPopstateEvent(RefPtr<SerializedScriptValue>&& stateObject);
     DocumentEventQueue& eventQueue() const final { return m_eventQueue; }
index a548f4e..0c2a13b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-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
@@ -31,6 +31,29 @@ struct EventInit {
     bool bubbles { false };
     bool cancelable { false };
     bool composed { false };
+
+    template<class Encoder> void encode(Encoder&) const;
+    template<class Decoder> static bool decode(Decoder&, EventInit&);
 };
 
+template<class Encoder>
+void EventInit::encode(Encoder& encoder) const
+{
+    encoder << bubbles;
+    encoder << cancelable;
+    encoder << composed;
+}
+
+template<class Decoder>
+bool EventInit::decode(Decoder& decoder, EventInit& eventInit)
+{
+    if (!decoder.decode(eventInit.bubbles))
+        return false;
+    if (!decoder.decode(eventInit.cancelable))
+        return false;
+    if (!decoder.decode(eventInit.composed))
+        return false;
+    return true;
+}
+
 }
index a6032f2..815b8bd 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-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,9 @@ public:
         unsigned short statusCode { 0 };
         int lineNumber { 0 };
         int columnNumber { 0 };
+
+        template<class Encoder> void encode(Encoder&) const;
+        template<class Decoder> static bool decode(Decoder&, Init&);
     };
 
     static Ref<SecurityPolicyViolationEvent> create(const AtomicString& type, const Init& initializer, IsTrusted isTrusted = IsTrusted::No)
@@ -119,4 +122,48 @@ private:
     int m_columnNumber;
 };
 
+template<class Encoder>
+void SecurityPolicyViolationEvent::Init::encode(Encoder& encoder) const
+{
+    encoder << static_cast<const EventInit&>(*this);
+    encoder << documentURI;
+    encoder << referrer;
+    encoder << blockedURI;
+    encoder << violatedDirective;
+    encoder << effectiveDirective;
+    encoder << originalPolicy;
+    encoder << sourceFile;
+    encoder << statusCode;
+    encoder << lineNumber;
+    encoder << columnNumber;
+}
+
+template<class Decoder>
+bool SecurityPolicyViolationEvent::Init::decode(Decoder& decoder, SecurityPolicyViolationEvent::Init& eventInit)
+{
+    if (!decoder.decode(static_cast<EventInit&>(eventInit)))
+        return false;
+    if (!decoder.decode(eventInit.documentURI))
+        return false;
+    if (!decoder.decode(eventInit.referrer))
+        return false;
+    if (!decoder.decode(eventInit.blockedURI))
+        return false;
+    if (!decoder.decode(eventInit.violatedDirective))
+        return false;
+    if (!decoder.decode(eventInit.effectiveDirective))
+        return false;
+    if (!decoder.decode(eventInit.originalPolicy))
+        return false;
+    if (!decoder.decode(eventInit.sourceFile))
+        return false;
+    if (!decoder.decode(eventInit.statusCode))
+        return false;
+    if (!decoder.decode(eventInit.lineNumber))
+        return false;
+    if (!decoder.decode(eventInit.columnNumber))
+        return false;
+    return true;
+}
+
 } // namespace WebCore
index 2ef6f49..9e09bd3 100644 (file)
@@ -75,7 +75,6 @@
 #include "SchemeRegistry.h"
 #include "ScriptableDocumentParser.h"
 #include "SecurityPolicy.h"
-#include "SecurityPolicyViolationEvent.h"
 #include "ServiceWorker.h"
 #include "ServiceWorkerProvider.h"
 #include "Settings.h"
@@ -2025,9 +2024,9 @@ void DocumentLoader::sendCSPViolationReport(URL&& reportURL, Ref<FormData>&& rep
     PingLoader::sendViolationReport(*m_frame, WTFMove(reportURL), WTFMove(report), ViolationReportType::ContentSecurityPolicy);
 }
 
-void DocumentLoader::dispatchSecurityPolicyViolationEvent(Ref<SecurityPolicyViolationEvent>&& violationEvent)
+void DocumentLoader::enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&& eventInit)
 {
-    m_frame->document()->enqueueDocumentEvent(WTFMove(violationEvent));
+    m_frame->document()->enqueueSecurityPolicyViolationEvent(WTFMove(eventInit));
 }
 
 } // namespace WebCore
index 071ef64..b187c1d 100644 (file)
@@ -41,6 +41,7 @@
 #include "ResourceLoaderOptions.h"
 #include "ResourceRequest.h"
 #include "ResourceResponse.h"
+#include "SecurityPolicyViolationEvent.h"
 #include "ServiceWorkerRegistrationData.h"
 #include "StringWithDirection.h"
 #include "StyleSheetContents.h"
@@ -411,7 +412,7 @@ private:
     // ContentSecurityPolicyClient
     WEBCORE_EXPORT void addConsoleMessage(MessageSource, MessageLevel, const String&, unsigned long requestIdentifier) final;
     WEBCORE_EXPORT void sendCSPViolationReport(URL&&, Ref<FormData>&&) final;
-    WEBCORE_EXPORT void dispatchSecurityPolicyViolationEvent(Ref<SecurityPolicyViolationEvent>&&) final;
+    WEBCORE_EXPORT void enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&&) final;
 
     Ref<CachedResourceLoader> m_cachedResourceLoader;
 
index 7e1b0d8..b145c17 100644 (file)
@@ -283,17 +283,17 @@ void DocumentThreadableLoader::redirectReceived(CachedResource& resource, Resour
         return completionHandler(WTFMove(request));
     }
 
+    if (platformStrategies()->loaderStrategy()->havePerformedSecurityChecks(redirectResponse)) {
+        completionHandler(WTFMove(request));
+        return;
+    }
+
     if (!isAllowedByContentSecurityPolicy(request.url(), redirectResponse.isNull() ? ContentSecurityPolicy::RedirectResponseReceived::No : ContentSecurityPolicy::RedirectResponseReceived::Yes)) {
         reportContentSecurityPolicyError(redirectResponse.url());
         clearResource();
         return completionHandler(WTFMove(request));
     }
 
-    if (platformStrategies()->loaderStrategy()->havePerformedSecurityChecks(redirectResponse)) {
-        completionHandler(WTFMove(request));
-        return;
-    }
-
     // Allow same origin requests to continue after allowing clients to audit the redirect.
     if (isAllowedRedirect(request.url()))
         return completionHandler(WTFMove(request));
@@ -461,14 +461,6 @@ void DocumentThreadableLoader::didFail(unsigned long, const ResourceError& error
     }
 #endif
 
-    // NetworkProcess might return a CSP violation as an AccessControl error in case of redirection.
-    // Let's recheck CSP to generate the report if needed.
-    // FIXME: We should introduce an error dedicated to CSP violation.
-    if (shouldPerformSecurityChecks() && error.isAccessControl() && error.failingURL().protocolIsInHTTPFamily() && !isAllowedByContentSecurityPolicy(error.failingURL(), ContentSecurityPolicy::RedirectResponseReceived::Yes)) {
-        reportContentSecurityPolicyError(m_resource->resourceRequest().url());
-        return;
-    }
-
     if (m_shouldLogError == ShouldLogError::Yes)
         logError(m_document, error, m_options.initiator);
 
@@ -670,7 +662,7 @@ void DocumentThreadableLoader::reportRedirectionWithBadScheme(const URL& url)
 
 void DocumentThreadableLoader::reportContentSecurityPolicyError(const URL& url)
 {
-    logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, url, "Cross-origin redirection denied by Content Security Policy.", ResourceError::Type::AccessControl));
+    logErrorAndFail(ResourceError(errorDomainWebKitInternal, 0, url, ASCIILiteral { "Blocked by Content Security Policy." }, ResourceError::Type::AccessControl));
 }
 
 void DocumentThreadableLoader::reportCrossOriginResourceSharingError(const URL& url)
index ce45806..5bfeec6 100644 (file)
@@ -696,15 +696,21 @@ void ContentSecurityPolicy::reportViolation(const String& effectiveViolatedDirec
     unsigned short httpStatusCode = m_selfSourceProtocol == "http" ? m_httpStatusCode : 0;
 
     // 1. Dispatch violation event.
-    bool canBubble = false;
-    bool cancelable = false;
-    auto violationEvent = SecurityPolicyViolationEvent::create(eventNames().securitypolicyviolationEvent, canBubble,
-        cancelable, info.documentURI, m_referrer, blockedURI, violatedDirective, effectiveViolatedDirective,
-        violatedDirectiveList.header(), info.sourceFile, httpStatusCode, info.lineNumber, info.columnNumber);
+    SecurityPolicyViolationEvent::Init violationEventInit;
+    violationEventInit.documentURI = info.documentURI;
+    violationEventInit.referrer = m_referrer;
+    violationEventInit.blockedURI = blockedURI;
+    violationEventInit.violatedDirective = violatedDirective;
+    violationEventInit.effectiveDirective = effectiveViolatedDirective;
+    violationEventInit.originalPolicy = violatedDirectiveList.header();
+    violationEventInit.sourceFile = info.sourceFile;
+    violationEventInit.statusCode = httpStatusCode;
+    violationEventInit.lineNumber =  info.lineNumber;
+    violationEventInit.columnNumber = info.columnNumber;
     if (m_client)
-        m_client->dispatchSecurityPolicyViolationEvent(WTFMove(violationEvent));
+        m_client->enqueueSecurityPolicyViolationEvent(WTFMove(violationEventInit));
     else
-        downcast<Document>(*m_scriptExecutionContext).enqueueDocumentEvent(WTFMove(violationEvent));
+        downcast<Document>(*m_scriptExecutionContext).enqueueSecurityPolicyViolationEvent(WTFMove(violationEventInit));
 
     // 2. Send violation report (if applicable).
     auto& reportURIs = violatedDirectiveList.reportURIs();
index 9125080..aa134dc 100644 (file)
@@ -100,7 +100,7 @@ public:
     WEBCORE_EXPORT bool allowFrameAncestors(const Vector<RefPtr<SecurityOrigin>>& ancestorOrigins, const URL&, bool overrideContentSecurityPolicy = false) const;
 
     enum class RedirectResponseReceived { No, Yes };
-    bool allowScriptFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
+    WEBCORE_EXPORT bool allowScriptFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
     bool allowImageFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
     bool allowStyleFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
     bool allowFontFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
@@ -110,7 +110,7 @@ public:
     bool allowMediaFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
 
     bool allowChildFrameFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
-    bool allowChildContextFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
+    WEBCORE_EXPORT bool allowChildContextFromSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
     WEBCORE_EXPORT bool allowConnectToSource(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
     bool allowFormAction(const URL&, RedirectResponseReceived = RedirectResponseReceived::No) const;
 
index 79fbbf2..eb4fe87 100644 (file)
 
 #pragma once
 
+#include "SecurityPolicyViolationEvent.h"
 #include <JavaScriptCore/ConsoleTypes.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
 class FormData;
-class SecurityPolicyViolationEvent;
 class URL;
 
 struct CSPInfo {
@@ -52,7 +52,7 @@ struct WEBCORE_EXPORT ContentSecurityPolicyClient {
 
     virtual void addConsoleMessage(MessageSource, MessageLevel, const String&, unsigned long requestIdentifier = 0) = 0;
     virtual void sendCSPViolationReport(URL&&, Ref<FormData>&&) = 0;
-    virtual void dispatchSecurityPolicyViolationEvent(Ref<SecurityPolicyViolationEvent>&&) = 0;
+    virtual void enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEvent::Init&&) = 0;
 };
 
 } // namespace WebCore
index 030a0bb..00c5d2d 100644 (file)
@@ -163,7 +163,7 @@ public:
     bool hiddenFromInspector() const { return m_hiddenFromInspector; }
     void setHiddenFromInspector(bool hiddenFromInspector) { m_hiddenFromInspector = hiddenFromInspector; }
 
-    enum class Requester { Unspecified, Main, XHR, Fetch, Media };
+    enum class Requester { Unspecified, Main, XHR, Fetch, Media, ImportScripts };
     Requester requester() const { return m_requester; }
     void setRequester(Requester requester) { m_requester = requester; }
 
index 5b340ff..1f91cd5 100644 (file)
@@ -60,6 +60,7 @@ void WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecuti
 
     // Only used for importScripts that prescribes NoCors mode.
     ASSERT(mode == FetchOptions::Mode::NoCors);
+    request->setRequester(ResourceRequest::Requester::ImportScripts);
 
     ThreadableLoaderOptions options;
     options.credentials = FetchOptions::Credentials::Include;
index d1815fc..0c3bd3f 100644 (file)
@@ -1,3 +1,40 @@
+2018-05-21  Daniel Bates  <dabates@apple.com>
+
+        REGRESSION (r231107): CSP report-only policies are ignored for beacon, importScripts, fetch(), EventSource, and XHR
+        https://bugs.webkit.org/show_bug.cgi?id=185789
+        <rdar://problem/40380175>
+
+        Reviewed by Andy Estes.
+
+        Have NetworkLoadChecker implement the ContentSecurityPolicyClient interface and support logging
+        console messages, sending CSP reports, and dispatching SecurityPolicyViolation events.
+
+        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+        (WebKit::NetworkConnectionToWebProcess::loadPing):
+        * NetworkProcess/NetworkLoadChecker.cpp:
+        (WebKit::NetworkLoadChecker::NetworkLoadChecker): Modified to take a reference to the NetworkConnectionToWebProcess,
+        the web page ID, the web frame ID, and the resource load identifier. These details are necessary
+        in order to implement the ContentSecurityPolicyClient interface.
+        (WebKit::NetworkLoadChecker::isAllowedByContentSecurityPolicy): Added.
+        (WebKit::NetworkLoadChecker::continueCheckingRequest): Write in terms of isAllowedByContentSecurityPolicy().
+        (WebKit::NetworkLoadChecker::contentSecurityPolicy): Pass ourself as the client so that we receive
+        delegate callbacks.
+        (WebKit::NetworkLoadChecker::addConsoleMessage): Added.
+        (WebKit::NetworkLoadChecker::sendCSPViolationReport): Added.
+        (WebKit::NetworkLoadChecker::enqueueSecurityPolicyViolationEvent): Added.
+        * NetworkProcess/NetworkLoadChecker.h:
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (NetworkResourceLoader::enqueueSecurityPolicyViolationEvent): Added.
+        * NetworkProcess/NetworkResourceLoader.h:
+        * NetworkProcess/PingLoad.cpp:
+        (WebKit::PingLoad::PingLoad): Modified to take a reference to the NetworkConnectionToWebProcess and pass
+        this through to the NetworkLoadChecker along with the web page ID, web frame ID and resource load identifier.
+        * NetworkProcess/PingLoad.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::enqueueSecurityPolicyViolationEvent): Added.
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in: Add message EnqueueSecurityPolicyViolationEvent.
+
 2018-05-21  Brian Burg  <bburg@apple.com>
 
         Web Automation: always return an empty cookie list if document.cookieURL() is empty
index 593a782..1ead39a 100644 (file)
@@ -266,7 +266,7 @@ void NetworkConnectionToWebProcess::loadPing(NetworkResourceLoadParameters&& loa
     };
 
     // PingLoad manages its own lifetime, deleting itself when its purpose has been fulfilled.
-    new PingLoad(WTFMove(loadParameters), WTFMove(completionHandler));
+    new PingLoad(WTFMove(loadParameters), *this, WTFMove(completionHandler));
 }
 
 void NetworkConnectionToWebProcess::didFinishPingLoad(uint64_t pingLoadIdentifier, const ResourceError& error, const ResourceResponse& response)
index 0a4d5c1..8e9c6f7 100644 (file)
 #include "config.h"
 #include "NetworkLoadChecker.h"
 
+#include "FormDataReference.h"
 #include "Logging.h"
 #include "NetworkCORSPreflightChecker.h"
+#include "NetworkConnectionToWebProcess.h"
 #include "NetworkProcess.h"
 #include "WebCompiledContentRuleList.h"
+#include "WebPageMessages.h"
 #include "WebUserContentController.h"
+#include <JavaScriptCore/ConsoleTypes.h>
 #include <WebCore/ContentSecurityPolicy.h>
 #include <WebCore/CrossOriginAccessControl.h>
 #include <WebCore/CrossOriginPreflightResultCache.h>
@@ -48,8 +52,12 @@ static inline bool isSameOrigin(const URL& url, const SecurityOrigin* origin)
     return url.protocolIsData() || url.protocolIsBlob() || !origin || origin->canRequest(url);
 }
 
-NetworkLoadChecker::NetworkLoadChecker(FetchOptions&& options, PAL::SessionID sessionID, HTTPHeaderMap&& originalRequestHeaders, URL&& url, RefPtr<SecurityOrigin>&& sourceOrigin, PreflightPolicy preflightPolicy, String&& referrer)
-    : m_options(WTFMove(options))
+NetworkLoadChecker::NetworkLoadChecker(NetworkConnectionToWebProcess& connection, uint64_t webPageID, uint64_t webFrameID, ResourceLoadIdentifier loadIdentifier, FetchOptions&& options, PAL::SessionID sessionID, HTTPHeaderMap&& originalRequestHeaders, URL&& url, RefPtr<SecurityOrigin>&& sourceOrigin, PreflightPolicy preflightPolicy, String&& referrer)
+    : m_connection(connection)
+    , m_webPageID(webPageID)
+    , m_webFrameID(webFrameID)
+    , m_loadIdentifier(loadIdentifier)
+    , m_options(WTFMove(options))
     , m_sessionID(sessionID)
     , m_originalRequestHeaders(WTFMove(originalRequestHeaders))
     , m_url(WTFMove(url))
@@ -178,6 +186,41 @@ void NetworkLoadChecker::checkRequest(ResourceRequest&& request, ValidationHandl
 #endif
 }
 
+bool NetworkLoadChecker::isAllowedByContentSecurityPolicy(const ResourceRequest& request)
+{
+    ASSERT(contentSecurityPolicy());
+    auto redirectResponseReceived = isRedirected() ? ContentSecurityPolicy::RedirectResponseReceived::Yes : ContentSecurityPolicy::RedirectResponseReceived::No;
+    switch (m_options.destination) {
+    case FetchOptions::Destination::Worker:
+    case FetchOptions::Destination::Serviceworker:
+    case FetchOptions::Destination::Sharedworker:
+        return contentSecurityPolicy()->allowChildContextFromSource(request.url(), redirectResponseReceived);
+    case FetchOptions::Destination::Script:
+        if (request.requester() == ResourceRequest::Requester::ImportScripts && !contentSecurityPolicy()->allowScriptFromSource(request.url(), redirectResponseReceived))
+            return false;
+        // FIXME: Check CSP for non-importScripts() initiated loads.
+        return true;
+    case FetchOptions::Destination::EmptyString:
+        return contentSecurityPolicy()->allowConnectToSource(request.url(), redirectResponseReceived);
+    case FetchOptions::Destination::Audio:
+    case FetchOptions::Destination::Document:
+    case FetchOptions::Destination::Embed:
+    case FetchOptions::Destination::Font:
+    case FetchOptions::Destination::Image:
+    case FetchOptions::Destination::Manifest:
+    case FetchOptions::Destination::Object:
+    case FetchOptions::Destination::Report:
+    case FetchOptions::Destination::Style:
+    case FetchOptions::Destination::Track:
+    case FetchOptions::Destination::Video:
+    case FetchOptions::Destination::Xslt:
+        // FIXME: Check CSP for these destinations.
+        return true;
+    }
+    ASSERT_NOT_REACHED();
+    return true;
+}
+
 void NetworkLoadChecker::continueCheckingRequest(ResourceRequest&& request, ValidationHandler&& handler)
 {
     if (auto* contentSecurityPolicy = this->contentSecurityPolicy()) {
@@ -188,9 +231,8 @@ void NetworkLoadChecker::continueCheckingRequest(ResourceRequest&& request, Vali
             if (url != request.url())
                 request.setURL(url);
         }
-        if (m_options.destination == FetchOptions::Destination::EmptyString && !contentSecurityPolicy->allowConnectToSource(request.url(), isRedirected() ? ContentSecurityPolicy::RedirectResponseReceived::Yes : ContentSecurityPolicy::RedirectResponseReceived::No)) {
-            String message = !isRedirected() ? ASCIILiteral("Blocked by Content Security Policy") : makeString("Blocked ", request.url().string(), " by Content Security Policy");
-            handler(accessControlErrorForValidationHandler(WTFMove(message)));
+        if (!isAllowedByContentSecurityPolicy(request)) {
+            handler(accessControlErrorForValidationHandler(ASCIILiteral { "Blocked by Content Security Policy." }));
             return;
         }
     }
@@ -320,7 +362,7 @@ ContentSecurityPolicy* NetworkLoadChecker::contentSecurityPolicy()
 {
     if (!m_contentSecurityPolicy && m_cspResponseHeaders) {
         // FIXME: Pass the URL of the protected resource instead of its origin.
-        m_contentSecurityPolicy = std::make_unique<ContentSecurityPolicy>(URL { URL { }, m_origin->toString() });
+        m_contentSecurityPolicy = std::make_unique<ContentSecurityPolicy>(URL { URL { }, m_origin->toString() }, this);
         m_contentSecurityPolicy->didReceiveHeaders(*m_cspResponseHeaders, String { m_referrer }, ContentSecurityPolicy::ReportParsingErrors::No);
     }
     return m_contentSecurityPolicy.get();
@@ -349,4 +391,22 @@ void NetworkLoadChecker::processContentExtensionRulesForLoad(ResourceRequest&& r
 }
 #endif // ENABLE(CONTENT_EXTENSIONS)
 
+void NetworkLoadChecker::addConsoleMessage(MessageSource messageSource, MessageLevel messageLevel, const String& message, unsigned long)
+{
+    if (m_webPageID && m_webFrameID)
+        m_connection->connection().send(Messages::WebPage::AddConsoleMessage { m_webFrameID,  messageSource, messageLevel, message, m_loadIdentifier }, m_webPageID);
+}
+
+void NetworkLoadChecker::sendCSPViolationReport(URL&& reportURL, Ref<FormData>&& report)
+{
+    if (m_webPageID && m_webFrameID)
+        m_connection->connection().send(Messages::WebPage::SendCSPViolationReport { m_webFrameID, WTFMove(reportURL), IPC::FormDataReference { WTFMove(report) } }, m_webPageID);
+}
+
+void NetworkLoadChecker::enqueueSecurityPolicyViolationEvent(WebCore::SecurityPolicyViolationEvent::Init&& eventInit)
+{
+    if (m_webPageID && m_webFrameID)
+        m_connection->connection().send(Messages::WebPage::EnqueueSecurityPolicyViolationEvent { m_webFrameID, WTFMove(eventInit) }, m_webPageID);
+}
+
 } // namespace WebKit
index c6597a0..62047d3 100644 (file)
 
 #include "NetworkContentRuleListManager.h"
 #include "NetworkResourceLoadParameters.h"
+#include <WebCore/ContentSecurityPolicyClient.h>
 #include <WebCore/ResourceError.h>
 #include <WebCore/ResourceResponse.h>
+#include <WebCore/SecurityPolicyViolationEvent.h>
 #include <wtf/CompletionHandler.h>
 #include <wtf/Expected.h>
 #include <wtf/WeakPtr.h>
@@ -39,11 +41,12 @@ class ContentSecurityPolicy;
 
 namespace WebKit {
 
+class NetworkConnectionToWebProcess;
 class NetworkCORSPreflightChecker;
 
-class NetworkLoadChecker {
+class NetworkLoadChecker : public WebCore::ContentSecurityPolicyClient {
 public:
-    NetworkLoadChecker(WebCore::FetchOptions&&, PAL::SessionID, WebCore::HTTPHeaderMap&&, WebCore::URL&&, RefPtr<WebCore::SecurityOrigin>&&, WebCore::PreflightPolicy, String&& referrer);
+    NetworkLoadChecker(NetworkConnectionToWebProcess&, uint64_t webPageID, uint64_t webFrameID, ResourceLoadIdentifier, WebCore::FetchOptions&&, PAL::SessionID, WebCore::HTTPHeaderMap&&, WebCore::URL&&, RefPtr<WebCore::SecurityOrigin>&&, WebCore::PreflightPolicy, String&& referrer);
     ~NetworkLoadChecker();
 
     using RequestOrError = Expected<WebCore::ResourceRequest, WebCore::ResourceError>;
@@ -75,6 +78,8 @@ private:
 
     void checkRequest(WebCore::ResourceRequest&&, ValidationHandler&&);
 
+    bool isAllowedByContentSecurityPolicy(const WebCore::ResourceRequest&);
+
     void continueCheckingRequest(WebCore::ResourceRequest&&, ValidationHandler&&);
 
     bool doesNotNeedCORSCheck(const WebCore::URL&) const;
@@ -94,6 +99,17 @@ private:
     void processContentExtensionRulesForLoad(WebCore::ResourceRequest&&, ContentExtensionCallback&&);
 #endif
 
+    // ContentSecurityPolicyClient
+    void addConsoleMessage(MessageSource, MessageLevel, const String&, unsigned long) final;
+    void sendCSPViolationReport(WebCore::URL&&, Ref<WebCore::FormData>&&) final;
+    void enqueueSecurityPolicyViolationEvent(WebCore::SecurityPolicyViolationEvent::Init&&) final;
+
+    // The connection, web page ID, web frame ID and load identifier are used for CSP reporting.
+    Ref<NetworkConnectionToWebProcess> m_connection;
+    uint64_t m_webPageID;
+    uint64_t m_webFrameID;
+    ResourceLoadIdentifier m_loadIdentifier;
+
     WebCore::FetchOptions m_options;
     WebCore::StoredCredentialsPolicy m_storedCredentialsPolicy;
     PAL::SessionID m_sessionID;
index 44a3254..b8025f3 100644 (file)
@@ -119,7 +119,7 @@ NetworkResourceLoader::NetworkResourceLoader(NetworkResourceLoadParameters&& par
     }
 
     if (synchronousReply || parameters.shouldRestrictHTTPResponseAccess) {
-        m_networkLoadChecker = std::make_unique<NetworkLoadChecker>(FetchOptions { m_parameters.options }, m_parameters.sessionID, HTTPHeaderMap { m_parameters.originalRequestHeaders }, URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy, originalRequest().httpReferrer());
+        m_networkLoadChecker = std::make_unique<NetworkLoadChecker>(m_connection, m_parameters.webPageID, m_parameters.webFrameID, identifier(), FetchOptions { m_parameters.options }, m_parameters.sessionID, HTTPHeaderMap { m_parameters.originalRequestHeaders }, URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy, originalRequest().httpReferrer());
         if (m_parameters.cspResponseHeaders)
             m_networkLoadChecker->setCSPResponseHeaders(ContentSecurityPolicyResponseHeaders { m_parameters.cspResponseHeaders.value() });
 #if ENABLE(CONTENT_EXTENSIONS)
@@ -1121,4 +1121,9 @@ void NetworkResourceLoader::sendCSPViolationReport(URL&& reportURL, Ref<FormData
     send(Messages::WebPage::SendCSPViolationReport { m_parameters.webFrameID, WTFMove(reportURL), IPC::FormDataReference { WTFMove(report) } }, m_parameters.webPageID);
 }
 
+void NetworkResourceLoader::enqueueSecurityPolicyViolationEvent(WebCore::SecurityPolicyViolationEvent::Init&& eventInit)
+{
+    send(Messages::WebPage::EnqueueSecurityPolicyViolationEvent { m_parameters.webFrameID, WTFMove(eventInit) }, m_parameters.webPageID);
+}
+
 } // namespace WebKit
index 773ca82..6197876 100644 (file)
@@ -35,6 +35,7 @@
 #include <JavaScriptCore/ConsoleTypes.h>
 #include <WebCore/ContentSecurityPolicyClient.h>
 #include <WebCore/ResourceResponse.h>
+#include <WebCore/SecurityPolicyViolationEvent.h>
 #include <WebCore/Timer.h>
 
 namespace WebCore {
@@ -42,7 +43,6 @@ class BlobDataFileReference;
 class FormData;
 class NetworkStorageSession;
 class ResourceRequest;
-class SecurityPolicyViolationEvent;
 }
 
 namespace WebKit {
@@ -175,7 +175,7 @@ private:
     // ContentSecurityPolicyClient
     void addConsoleMessage(MessageSource, MessageLevel, const String&, unsigned long) final;
     void sendCSPViolationReport(WebCore::URL&&, Ref<WebCore::FormData>&&) final;
-    void dispatchSecurityPolicyViolationEvent(Ref<WebCore::SecurityPolicyViolationEvent>&&) final { }; // No observable effect for frame-ancestors violation.
+    void enqueueSecurityPolicyViolationEvent(WebCore::SecurityPolicyViolationEvent::Init&&) final;
 
     const NetworkResourceLoadParameters m_parameters;
 
index e3c8aa7..1aece47 100644 (file)
@@ -38,11 +38,11 @@ namespace WebKit {
 
 using namespace WebCore;
 
-PingLoad::PingLoad(NetworkResourceLoadParameters&& parameters, WTF::CompletionHandler<void(const ResourceError&, const ResourceResponse&)>&& completionHandler)
+PingLoad::PingLoad(NetworkResourceLoadParameters&& parameters, NetworkConnectionToWebProcess& connection, WTF::CompletionHandler<void(const ResourceError&, const ResourceResponse&)>&& completionHandler)
     : m_parameters(WTFMove(parameters))
     , m_completionHandler(WTFMove(completionHandler))
     , m_timeoutTimer(*this, &PingLoad::timeoutTimerFired)
-    , m_networkLoadChecker(makeUniqueRef<NetworkLoadChecker>(FetchOptions { m_parameters.options}, m_parameters.sessionID, WTFMove(m_parameters.originalRequestHeaders), URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy, m_parameters.request.httpReferrer()))
+    , m_networkLoadChecker(makeUniqueRef<NetworkLoadChecker>(connection, m_parameters.webPageID, m_parameters.webFrameID, m_parameters.identifier, FetchOptions { m_parameters.options}, m_parameters.sessionID, WTFMove(m_parameters.originalRequestHeaders), URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy, m_parameters.request.httpReferrer()))
 {
 
     if (m_parameters.cspResponseHeaders)
index 8b3c7d3..b93815a 100644 (file)
@@ -40,11 +40,12 @@ class URL;
 
 namespace WebKit {
 
+class NetworkConnectionToWebProcess;
 class NetworkLoadChecker;
 
 class PingLoad final : private NetworkDataTaskClient {
 public:
-    PingLoad(NetworkResourceLoadParameters&&, WTF::CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)>&&);
+    PingLoad(NetworkResourceLoadParameters&&, NetworkConnectionToWebProcess&, WTF::CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)>&&);
     
 private:
     ~PingLoad();
index 84a43c9..c1a313e 100644 (file)
@@ -3329,6 +3329,18 @@ void WebPage::sendCSPViolationReport(uint64_t frameID, const WebCore::URL& repor
         PingLoader::sendViolationReport(*frame->coreFrame(), reportURL, report.releaseNonNull(), ViolationReportType::ContentSecurityPolicy);
 }
 
+void WebPage::enqueueSecurityPolicyViolationEvent(uint64_t frameID, SecurityPolicyViolationEvent::Init&& eventInit)
+{
+    auto* frame = WebProcess::singleton().webFrame(frameID);
+    if (!frame)
+        return;
+    auto* coreFrame = frame->coreFrame();
+    if (!coreFrame)
+        return;
+    if (auto* document = coreFrame->document())
+        document->enqueueSecurityPolicyViolationEvent(WTFMove(eventInit));
+}
+
 NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager()
 {
     if (m_notificationPermissionRequestManager)
index 899d9a0..67effdb 100644 (file)
@@ -59,6 +59,7 @@
 #include <WebCore/Page.h>
 #include <WebCore/PageOverlay.h>
 #include <WebCore/PluginData.h>
+#include <WebCore/SecurityPolicyViolationEvent.h>
 #include <WebCore/UserActivity.h>
 #include <WebCore/UserContentTypes.h>
 #include <WebCore/UserInterfaceLayoutDirection.h>
@@ -310,6 +311,7 @@ public:
 
     void addConsoleMessage(uint64_t frameID, MessageSource, MessageLevel, const String&, uint64_t requestID = 0);
     void sendCSPViolationReport(uint64_t frameID, const WebCore::URL& reportURL, IPC::FormDataReference&&);
+    void enqueueSecurityPolicyViolationEvent(uint64_t frameID, WebCore::SecurityPolicyViolationEvent::Init&&);
 
     // -- Called by the DrawingArea.
     // FIXME: We could genericize these into a DrawingArea client interface. Would that be beneficial?
index 888b996..41b5147 100644 (file)
@@ -29,6 +29,7 @@ messages -> WebPage LegacyReceiver {
 
     AddConsoleMessage(uint64_t frameID, enum MessageSource messageSource, enum MessageLevel messageLevel, String message, uint64_t requestID)
     SendCSPViolationReport(uint64_t frameID, WebCore::URL reportURL, IPC::FormDataReference reportData)
+    EnqueueSecurityPolicyViolationEvent(uint64_t frameID, WebCore::SecurityPolicyViolationEvent::Init eventInit)
 
 #if PLATFORM(COCOA)
     SetTopContentInsetFenced(float contentInset, IPC::Attachment fencePort)