CSP: Use the served CSP header for dedicated workers
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Feb 2016 03:10:00 +0000 (03:10 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Feb 2016 03:10:00 +0000 (03:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153157
<rdar://problem/24383254>
And
https://bugs.webkit.org/show_bug.cgi?id=153156
<rdar://problem/24383246>

Patch by Daniel Bates <dabates@apple.com> on 2016-01-31
Reviewed by Brent Fulgham.

Source/WebCore:

Inspired by Blink commit:
<https://src.chromium.org/viewvc/blink?revision=194143&view=revision>

Implement support for respecting Content Security Policy (CSP) HTTP headers included in the
HTTP response for a Web Worker's script as per section Workers of the CSP 2.0 spec,
<https://w3c.github.io/webappsec-csp/2/#processing-model-workers> (29 August 2015).

Currently a Web Worker always inherits the CSP of its owner document. Instead a web worker
will inherit the CSP of its owner document only if its script is incapable of defining a
content security policy (i.e. its origin is a globally unique identifier). Otherwise, the
CSP HTTP headers delivered with the script will be used to define the CSP for the worker.

Tests: fast/workers/worker-inherits-csp-blocks-eval.html
       fast/workers/worker-inherits-csp-blocks-xhr.html
       http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval.html

* CMakeLists.txt: Add file ContentSecurityPolicyResponseHeaders.cpp.
* WebCore.vcxproj/WebCore.vcxproj: Add files ContentSecurityPolicyResponseHeaders.{cpp, h}.
* WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* dom/Document.cpp:
(WebCore::Document::processHttpEquiv): Update code to use enum class ContentSecurityPolicyHeaderType.
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::didBeginDocument): Extract logic to collect Content Security Policy HTTP headers
into class ContentSecurityPolicyResponseHeaders and make use of it here.
* page/csp/ContentSecurityPolicy.cpp:
(WebCore::CSPDirectiveList::headerType): Modified to use enum class ContentSecurityPolicyHeaderType.
(WebCore::CSPDirectiveList::CSPDirectiveList): Ditto.
(WebCore::CSPDirectiveList::create): Ditto.
(WebCore::ContentSecurityPolicy::responseHeaders): Creates and returns a ContentSecurityPolicyResponseHeaders
object with the parsed CSP policy headers.
(WebCore::ContentSecurityPolicy::didReceiveHeaders): Processed the CSP policy headers represented by the
specified ContentSecurityPolicyResponseHeaders object.
(WebCore::ContentSecurityPolicy::deprecatedHeader): Deleted.
(WebCore::ContentSecurityPolicy::deprecatedHeaderType): Deleted.
* page/csp/ContentSecurityPolicy.h: Defines a class that represents a collection of CSP policy headers.
This class has two purposes:
    - It extracts the CSP policy headers from a HTTP response (ResourceResponse object). We make use of
    this functionality in both FrameLoader::didBeginDocument() and Worker::didReceiveResponse().
    - It serves as a memento that externalizes the internal CSP policy details of an instance of
    ContentSecurityPolicy. We make use of this memento functionality to support inheriting the
    CSP policy of the worker's owner document in a thread-safe manner. You can create and restore
    a memento using ContentSecurityPolicy::responseHeaders() and ContentSecurityPolicy::didReceiveHeaders(), respectively.
* page/csp/ContentSecurityPolicyResponseHeaders.cpp: Added.
(WebCore::ContentSecurityPolicyResponseHeaders::ContentSecurityPolicyResponseHeaders): Extracts the
CSP HTTP headers from a ResourceResponse object.
(WebCore::ContentSecurityPolicyResponseHeaders::isolatedCopy): Make a copy of this object that is
safe to pass to another thread.
* page/csp/ContentSecurityPolicyResponseHeaders.h: Added.
* workers/DedicatedWorkerGlobalScope.cpp:
(WebCore::DedicatedWorkerGlobalScope::create): Modified to use class ContentSecurityPolicyResponseHeaders.
* workers/DedicatedWorkerGlobalScope.h:
* workers/DedicatedWorkerThread.cpp:
(WebCore::DedicatedWorkerThread::create): Ditto.
(WebCore::DedicatedWorkerThread::DedicatedWorkerThread): Ditto.
(WebCore::DedicatedWorkerThread::createWorkerGlobalScope): Ditto.
* workers/DedicatedWorkerThread.h:
* workers/Worker.cpp:
(WebCore::Worker::didReceiveResponse): Create a ContentSecurityPolicyResponseHeaders if the origin of
the worker's script is capable of providing a CSP. Otherwise, we will inherit the CSP of the worker's owner
document in Worker::notifyFinished().
(WebCore::Worker::notifyFinished): Pass the appropriate CSP response headers to WorkerMessagingProxy::startWorkerGlobalScope().
* workers/Worker.h:
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::applyContentSecurityPolicyResponseHeaders): Renamed; formerly named applyContentSecurityPolicyFromString().
Modified to take a ContentSecurityPolicyResponseHeaders and apply it to the ContentSecurityPolicy object associated with the worker.
(WebCore::WorkerGlobalScope::applyContentSecurityPolicyFromString): Deleted.
* workers/WorkerGlobalScope.h:
* workers/WorkerMessagingProxy.cpp:
(WebCore::WorkerMessagingProxy::startWorkerGlobalScope): Pass the worker's ContentSecurityPolicyResponseHeaders object.
* workers/WorkerThread.cpp:
(WebCore::WorkerThreadStartupData::WorkerThreadStartupData): Added field m_contentSecurityPolicyResponseHeaders to store
the CSP response headers to be applied to the worker's ContentSecurityPolicy object.
(WebCore::WorkerThread::WorkerThread): Modified to use ContentSecurityPolicyResponseHeaders.
(WebCore::WorkerThread::workerThread): Pass the ContentSecurityPolicyResponseHeaders object from the start up data struct
to DedicatedWorkerThread::createWorkerGlobalScope().
* workers/WorkerThread.h:

LayoutTests:

Add new tests to ensure we block eval() in blob-, file-URL workers and block XHR in a file-URL worker.

* TestExpectations: Remove now passing tests http/tests/security/contentSecurityPolicy/worker-{multiple-csp-headers, without-own-csp}.html
and update the associated bug # for tests that fail.
* fast/workers/resources/worker-inherits-csp-blocks-eval.js: Added.
(catch):
* fast/workers/resources/worker-inherits-csp-blocks-xhr.js: Added.
(catch):
* fast/workers/worker-inherits-csp-blocks-eval-expected.txt: Added.
* fast/workers/worker-inherits-csp-blocks-eval.html: Added.
* fast/workers/worker-inherits-csp-blocks-xhr-expected.txt: Added.
* fast/workers/worker-inherits-csp-blocks-xhr.html: Added.
* http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval.html: Added.
* http/tests/security/contentSecurityPolicy/worker-multiple-csp-headers-expected.txt: Updated expected results as
the result was incorrect.
* http/tests/security/contentSecurityPolicy/worker-without-own-csp-expected.txt: Ditto.

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

36 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/fast/workers/resources/worker-inherits-csp-blocks-eval.js [new file with mode: 0644]
LayoutTests/fast/workers/resources/worker-inherits-csp-blocks-xhr.js [new file with mode: 0644]
LayoutTests/fast/workers/worker-inherits-csp-blocks-eval-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/worker-inherits-csp-blocks-eval.html [new file with mode: 0644]
LayoutTests/fast/workers/worker-inherits-csp-blocks-xhr-expected.txt [new file with mode: 0644]
LayoutTests/fast/workers/worker-inherits-csp-blocks-xhr.html [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval.html [new file with mode: 0644]
LayoutTests/http/tests/security/contentSecurityPolicy/worker-multiple-csp-headers-expected.txt
LayoutTests/http/tests/security/contentSecurityPolicy/worker-without-own-csp-expected.txt
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.cpp
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/page/csp/ContentSecurityPolicy.cpp
Source/WebCore/page/csp/ContentSecurityPolicy.h
Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.cpp [new file with mode: 0644]
Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h [new file with mode: 0644]
Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp
Source/WebCore/workers/DedicatedWorkerGlobalScope.h
Source/WebCore/workers/DedicatedWorkerThread.cpp
Source/WebCore/workers/DedicatedWorkerThread.h
Source/WebCore/workers/Worker.cpp
Source/WebCore/workers/Worker.h
Source/WebCore/workers/WorkerGlobalScope.cpp
Source/WebCore/workers/WorkerGlobalScope.h
Source/WebCore/workers/WorkerGlobalScopeProxy.h
Source/WebCore/workers/WorkerMessagingProxy.cpp
Source/WebCore/workers/WorkerMessagingProxy.h
Source/WebCore/workers/WorkerThread.cpp
Source/WebCore/workers/WorkerThread.h

index 4c9dbb2..7e53a7e 100644 (file)
@@ -1,3 +1,47 @@
+2016-01-31  Daniel Bates  <dabates@apple.com>
+
+        CSP: Use the served CSP header for dedicated workers
+        https://bugs.webkit.org/show_bug.cgi?id=153157
+        <rdar://problem/24383254>
+        And
+        https://bugs.webkit.org/show_bug.cgi?id=153156
+        <rdar://problem/24383246>
+
+        Reviewed by Brent Fulgham.
+
+        Add new tests to ensure we block eval() in blob-, file-URL workers and block XHR in a file-URL worker.
+
+        * TestExpectations: Remove now passing tests http/tests/security/contentSecurityPolicy/worker-{multiple-csp-headers, without-own-csp}.html
+        and update the associated bug # for tests that fail.
+        * fast/workers/resources/worker-inherits-csp-blocks-eval.js: Added.
+        (catch):
+        * fast/workers/resources/worker-inherits-csp-blocks-xhr.js: Added.
+        (catch):
+        * fast/workers/worker-inherits-csp-blocks-eval-expected.txt: Added.
+        * fast/workers/worker-inherits-csp-blocks-eval.html: Added.
+        * fast/workers/worker-inherits-csp-blocks-xhr-expected.txt: Added.
+        * fast/workers/worker-inherits-csp-blocks-xhr.html: Added.
+        * http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval.html: Added.
+        * http/tests/security/contentSecurityPolicy/worker-multiple-csp-headers-expected.txt: Updated expected results as
+        the result was incorrect.
+        * http/tests/security/contentSecurityPolicy/worker-without-own-csp-expected.txt: Ditto.
+
+2016-01-27  Daniel Bates  <dabates@apple.com>
+
+        CSP: Use the served CSP header for dedicated workers
+        https://bugs.webkit.org/show_bug.cgi?id=153157
+        And
+        https://bugs.webkit.org/show_bug.cgi?id=153156
+
+        Reviewed by Brent Fulgham.
+
+        Remove some tests that now pass and update the expected results of existing tests.
+
+        * TestExpectations:
+        * http/tests/security/contentSecurityPolicy/worker-multiple-csp-headers-expected.txt:
+        * http/tests/security/contentSecurityPolicy/worker-without-own-csp-expected.txt:
+
 2016-01-31  Hunseop Jeong  <hs85.jeong@samsung.com>
 
         Unreviewed. EFL gardening: rebaseline tests after r195740. (more to follow)
index 522e5a0..e8b0968 100644 (file)
@@ -799,6 +799,7 @@ webkit.org/b/52185 fast/css/vertical-align-baseline-rowspan-010.html [ ImageOnly
 # Content Security Policy failures
 webkit.org/b/69359 http/tests/security/contentSecurityPolicy/connect-src-eventsource-redirect-to-blocked.html [ Failure ]
 webkit.org/b/69359 http/tests/security/contentSecurityPolicy/connect-src-xmlhttprequest-redirect-to-blocked.html [ Failure ]
+webkit.org/b/69359 http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp.html [ Failure ]
 webkit.org/b/111869 http/tests/security/contentSecurityPolicy/eval-blocked-and-sends-report.html
 webkit.org/b/115700 http/tests/security/contentSecurityPolicy/inline-event-handler-blocked-after-injecting-meta.html [ Failure ]
 webkit.org/b/115702 http/tests/security/contentSecurityPolicy/report-cross-origin-no-cookies.html [ Failure ]
@@ -816,11 +817,6 @@ webkit.org/b/153153 http/tests/security/contentSecurityPolicy/object-src-param-s
 webkit.org/b/153153 http/tests/security/contentSecurityPolicy/object-src-param-url-blocked.html
 webkit.org/b/153154 http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html
 webkit.org/b/153155 http/tests/security/contentSecurityPolicy/style-src-blocked-error-event.html
-webkit.org/b/153156 http/tests/security/contentSecurityPolicy/worker-multiple-csp-headers.html [ Failure ]
-webkit.org/b/153157 http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp.html [ Failure ]
-webkit.org/b/153157 http/tests/security/contentSecurityPolicy/worker-importscripts-blocked.html [ Failure ]
-webkit.org/b/153157 http/tests/security/contentSecurityPolicy/worker-script-src.html [ Failure ]
-webkit.org/b/153157 http/tests/security/contentSecurityPolicy/worker-without-own-csp.html [ Failure ]
 webkit.org/b/153158 http/tests/security/contentSecurityPolicy/blob-urls-match-self.html [ Failure ]
 webkit.org/b/153159 http/tests/security/contentSecurityPolicy/image-document-default-src-none.html [ Failure ]
 webkit.org/b/153160 http/tests/security/contentSecurityPolicy/object-src-does-not-affect-child.html [ Failure ]
@@ -842,6 +838,8 @@ webkit.org/b/153166 webkit.org/b/153242 http/tests/security/contentSecurityPolic
 webkit.org/b/153167 http/tests/security/contentSecurityPolicy/sandbox-report-only.html [ Failure ]
 webkit.org/b/153168 http/tests/security/contentSecurityPolicy/source-list-parsing-07.html [ Failure ]
 webkit.org/b/153170 http/tests/security/contentSecurityPolicy/source-list-parsing-paths-03.html [ Failure ]
+webkit.org/b/153562 http/tests/security/contentSecurityPolicy/worker-importscripts-blocked.html [ Failure ]
+webkit.org/b/153562 http/tests/security/contentSecurityPolicy/worker-script-src.html [ Failure ]
 http/tests/security/contentSecurityPolicy/script-src-blocked-error-event.html [ Pass Failure ]
 http/tests/security/contentSecurityPolicy/1.1/frame-ancestors/frame-ancestors-overrides-xfo.html # Needs expected file.
 http/tests/security/contentSecurityPolicy/1.1/scripthash-default-src.html # Needs expected file.
diff --git a/LayoutTests/fast/workers/resources/worker-inherits-csp-blocks-eval.js b/LayoutTests/fast/workers/resources/worker-inherits-csp-blocks-eval.js
new file mode 100644 (file)
index 0000000..2968987
--- /dev/null
@@ -0,0 +1,14 @@
+var exception;
+try {
+    eval("1 + 0");
+} catch (e) {
+    exception = e;
+}
+if (!exception)
+    self.postMessage("FAIL should throw EvalError. But did not throw an exception.");
+else {
+    if (exception instanceof EvalError)
+        self.postMessage("PASS threw exception " + exception + ".");
+    else
+        self.postMessage("FAIL should throw EvalError. Threw exception " + exception + ".");
+}
diff --git a/LayoutTests/fast/workers/resources/worker-inherits-csp-blocks-xhr.js b/LayoutTests/fast/workers/resources/worker-inherits-csp-blocks-xhr.js
new file mode 100644 (file)
index 0000000..c6210fa
--- /dev/null
@@ -0,0 +1,19 @@
+var exception;
+try {
+    var xhr = new XMLHttpRequest;
+    var isAsynchronous = false;
+    xhr.open("GET", "non-existent-file", isAsynchronous);
+    xhr.send();
+} catch (e) {
+    exception = e;
+}
+// FIXME: We should be throwing a DOMException.NETWORK_ERR. See <https://bugs.webkit.org/show_bug.cgi?id=153598>.
+var expectedExceptionCode = 18; // DOMException.SECURITY_ERR
+if (!exception)
+    self.postMessage("FAIL should throw " + expectedExceptionCode + ". But did not throw an exception.");
+else {
+    if (exception.code === expectedExceptionCode)
+        self.postMessage("PASS threw exception " + exception + ".");
+    else
+        self.postMessage("FAIL should throw " + expectedExceptionCode + ". Threw exception " + exception + ".");
+}
diff --git a/LayoutTests/fast/workers/worker-inherits-csp-blocks-eval-expected.txt b/LayoutTests/fast/workers/worker-inherits-csp-blocks-eval-expected.txt
new file mode 100644 (file)
index 0000000..fc42b9e
--- /dev/null
@@ -0,0 +1,4 @@
+This tests that the Content Security Policy (CSP) of the owner document (this page) blocks a file-URL Web Worker from using eval() because the parent's CSP does not list unsafe-eval in script-src.
+
+PASS threw exception EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+.
diff --git a/LayoutTests/fast/workers/worker-inherits-csp-blocks-eval.html b/LayoutTests/fast/workers/worker-inherits-csp-blocks-eval.html
new file mode 100644 (file)
index 0000000..048ed53
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<p>This tests that the Content Security Policy (CSP) of the owner document (this page) blocks a file-URL Web Worker from using <code>eval()</code> because the parent's CSP does not list <code>unsafe-eval</code> in script-src.</p>
+<pre id="result"></pre>
+<script>
+window.onmessage = function (event)
+{
+    document.getElementById("result").textContent = event.data;
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var worker;
+try {
+    worker = new Worker("resources/worker-inherits-csp-blocks-eval.js");
+    worker.onmessage = function (event) { window.postMessage(event.data, "*") };
+} catch (exception) {
+    window.postMessage("FAIL should not have thrown an exception when creating worker. Threw exception " + exception + ".", "*");
+}
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/workers/worker-inherits-csp-blocks-xhr-expected.txt b/LayoutTests/fast/workers/worker-inherits-csp-blocks-xhr-expected.txt
new file mode 100644 (file)
index 0000000..cf9e010
--- /dev/null
@@ -0,0 +1,5 @@
+CONSOLE MESSAGE: Refused to connect to 'non-existent-file' because it violates the following Content Security Policy directive: "connect-src 'none'".
+
+This tests that the Content Security Policy (CSP) of the owner document (this page) blocks a file-URL Web Worker from making an XHR request because the parent's CSP contains "connect-src 'none'"
+
+PASS threw exception Error: SecurityError: DOM Exception 18.
diff --git a/LayoutTests/fast/workers/worker-inherits-csp-blocks-xhr.html b/LayoutTests/fast/workers/worker-inherits-csp-blocks-xhr.html
new file mode 100644 (file)
index 0000000..d83e036
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; connect-src 'none'">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<p>This tests that the Content Security Policy (CSP) of the owner document (this page) blocks a file-URL Web Worker from making an XHR request because the parent's CSP contains &quot;connect-src 'none'&quot;</p>
+<pre id="result"></pre>
+<script>
+window.onmessage = function (event)
+{
+    document.getElementById("result").textContent = event.data;
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var worker;
+try {
+    worker = new Worker("resources/worker-inherits-csp-blocks-xhr.js");
+    worker.onmessage = function (event) { window.postMessage(event.data, "*") };
+} catch (exception) {
+    window.postMessage("FAIL should not have thrown an exception when creating worker. Threw exception " + exception + ".", "*");
+}
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval-expected.txt
new file mode 100644 (file)
index 0000000..8a7b733
--- /dev/null
@@ -0,0 +1,4 @@
+This tests that the Content Security Policy (CSP) of the owner document (this page) blocks a blob-URL Web Worker from using eval() because the parent's CSP does not list unsafe-eval in script-src.
+
+PASS threw exception EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+.
diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval.html b/LayoutTests/http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval.html
new file mode 100644 (file)
index 0000000..d1e9101
--- /dev/null
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!-- FIXME: Remove 'self' from script-src once we fix <https://bugs.webkit.org/show_bug.cgi?id=153158>. -->
+<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<p>This tests that the Content Security Policy (CSP) of the owner document (this page) blocks a blob-URL Web Worker from using <code>eval()</code> because the parent's CSP does not list <code>unsafe-eval</code> in script-src.</p>
+<pre id="result"></pre>
+<script>
+window.onmessage = function (event)
+{
+    document.getElementById("result").textContent = event.data;
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var script = [
+    'var exception;',
+    'try {',
+    '    eval("1 + 0");',
+    '} catch (e) {',
+    '    exception = e;',
+    '}',
+    'if (!exception)',
+    '    self.postMessage("FAIL should throw EvalError. But did not throw an exception.");',
+    'else {',
+    '    if (exception instanceof EvalError)',
+    '        self.postMessage("PASS threw exception " + exception + ".");',
+    '    else',
+    '        self.postMessage("FAIL should throw EvalError. Threw exception " + exception + ".");',
+    '}',
+].join("\n");
+
+var worker;
+try {
+    worker = new Worker(window.URL.createObjectURL(new Blob([script])));
+    worker.onmessage = function (event) { window.postMessage(event.data, "*") };
+} catch (exception) {
+    window.postMessage("FAIL should not have thrown an exception when creating worker. Threw exception " + exception + ".", "*");
+}
+</script>
+</body>
+</html>
index 20b538b..0100533 100644 (file)
@@ -1,3 +1,5 @@
+CONSOLE MESSAGE: Refused to connect to 'http://127.0.0.1:8000/xmlhttprequest/resources/get.txt' because it violates the following Content Security Policy directive: "connect-src 'none'".
+
 
 PASS Worker can have multiple CSP headers 
 
index aabded2..2497bed 100644 (file)
@@ -2067,6 +2067,7 @@ set(WebCore_SOURCES
     page/animation/KeyframeAnimation.cpp
 
     page/csp/ContentSecurityPolicy.cpp
+    page/csp/ContentSecurityPolicyResponseHeaders.cpp
 
     page/scrolling/AxisScrollSnapOffsets.cpp
     page/scrolling/ScrollLatchingState.cpp
index cb5b1de..f47bcda 100644 (file)
@@ -1,3 +1,92 @@
+2016-01-31  Daniel Bates  <dabates@apple.com>
+
+        CSP: Use the served CSP header for dedicated workers
+        https://bugs.webkit.org/show_bug.cgi?id=153157
+        <rdar://problem/24383254>
+        And
+        https://bugs.webkit.org/show_bug.cgi?id=153156
+        <rdar://problem/24383246>
+
+        Reviewed by Brent Fulgham.
+
+        Inspired by Blink commit:
+        <https://src.chromium.org/viewvc/blink?revision=194143&view=revision>
+
+        Implement support for respecting Content Security Policy (CSP) HTTP headers included in the
+        HTTP response for a Web Worker's script as per section Workers of the CSP 2.0 spec,
+        <https://w3c.github.io/webappsec-csp/2/#processing-model-workers> (29 August 2015).
+
+        Currently a Web Worker always inherits the CSP of its owner document. Instead a web worker
+        will inherit the CSP of its owner document only if its script is incapable of defining a
+        content security policy (i.e. its origin is a globally unique identifier). Otherwise, the
+        CSP HTTP headers delivered with the script will be used to define the CSP for the worker.
+
+        Tests: fast/workers/worker-inherits-csp-blocks-eval.html
+               fast/workers/worker-inherits-csp-blocks-xhr.html
+               http/tests/security/contentSecurityPolicy/worker-blob-inherits-csp-blocks-eval.html
+
+        * CMakeLists.txt: Add file ContentSecurityPolicyResponseHeaders.cpp.
+        * WebCore.vcxproj/WebCore.vcxproj: Add files ContentSecurityPolicyResponseHeaders.{cpp, h}.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * dom/Document.cpp:
+        (WebCore::Document::processHttpEquiv): Update code to use enum class ContentSecurityPolicyHeaderType.
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::didBeginDocument): Extract logic to collect Content Security Policy HTTP headers
+        into class ContentSecurityPolicyResponseHeaders and make use of it here.
+        * page/csp/ContentSecurityPolicy.cpp:
+        (WebCore::CSPDirectiveList::headerType): Modified to use enum class ContentSecurityPolicyHeaderType.
+        (WebCore::CSPDirectiveList::CSPDirectiveList): Ditto.
+        (WebCore::CSPDirectiveList::create): Ditto.
+        (WebCore::ContentSecurityPolicy::responseHeaders): Creates and returns a ContentSecurityPolicyResponseHeaders
+        object with the parsed CSP policy headers.
+        (WebCore::ContentSecurityPolicy::didReceiveHeaders): Processed the CSP policy headers represented by the
+        specified ContentSecurityPolicyResponseHeaders object.
+        (WebCore::ContentSecurityPolicy::deprecatedHeader): Deleted.
+        (WebCore::ContentSecurityPolicy::deprecatedHeaderType): Deleted.
+        * page/csp/ContentSecurityPolicy.h: Defines a class that represents a collection of CSP policy headers.
+        This class has two purposes:
+            - It extracts the CSP policy headers from a HTTP response (ResourceResponse object). We make use of
+            this functionality in both FrameLoader::didBeginDocument() and Worker::didReceiveResponse().
+            - It serves as a memento that externalizes the internal CSP policy details of an instance of
+            ContentSecurityPolicy. We make use of this memento functionality to support inheriting the
+            CSP policy of the worker's owner document in a thread-safe manner. You can create and restore
+            a memento using ContentSecurityPolicy::responseHeaders() and ContentSecurityPolicy::didReceiveHeaders(), respectively.
+        * page/csp/ContentSecurityPolicyResponseHeaders.cpp: Added.
+        (WebCore::ContentSecurityPolicyResponseHeaders::ContentSecurityPolicyResponseHeaders): Extracts the
+        CSP HTTP headers from a ResourceResponse object.
+        (WebCore::ContentSecurityPolicyResponseHeaders::isolatedCopy): Make a copy of this object that is
+        safe to pass to another thread.
+        * page/csp/ContentSecurityPolicyResponseHeaders.h: Added.
+        * workers/DedicatedWorkerGlobalScope.cpp:
+        (WebCore::DedicatedWorkerGlobalScope::create): Modified to use class ContentSecurityPolicyResponseHeaders.
+        * workers/DedicatedWorkerGlobalScope.h:
+        * workers/DedicatedWorkerThread.cpp:
+        (WebCore::DedicatedWorkerThread::create): Ditto.
+        (WebCore::DedicatedWorkerThread::DedicatedWorkerThread): Ditto.
+        (WebCore::DedicatedWorkerThread::createWorkerGlobalScope): Ditto.
+        * workers/DedicatedWorkerThread.h:
+        * workers/Worker.cpp:
+        (WebCore::Worker::didReceiveResponse): Create a ContentSecurityPolicyResponseHeaders if the origin of
+        the worker's script is capable of providing a CSP. Otherwise, we will inherit the CSP of the worker's owner
+        document in Worker::notifyFinished().
+        (WebCore::Worker::notifyFinished): Pass the appropriate CSP response headers to WorkerMessagingProxy::startWorkerGlobalScope().
+        * workers/Worker.h:
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::applyContentSecurityPolicyResponseHeaders): Renamed; formerly named applyContentSecurityPolicyFromString().
+        Modified to take a ContentSecurityPolicyResponseHeaders and apply it to the ContentSecurityPolicy object associated with the worker.
+        (WebCore::WorkerGlobalScope::applyContentSecurityPolicyFromString): Deleted.
+        * workers/WorkerGlobalScope.h:
+        * workers/WorkerMessagingProxy.cpp:
+        (WebCore::WorkerMessagingProxy::startWorkerGlobalScope): Pass the worker's ContentSecurityPolicyResponseHeaders object.
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThreadStartupData::WorkerThreadStartupData): Added field m_contentSecurityPolicyResponseHeaders to store
+        the CSP response headers to be applied to the worker's ContentSecurityPolicy object.
+        (WebCore::WorkerThread::WorkerThread): Modified to use ContentSecurityPolicyResponseHeaders.
+        (WebCore::WorkerThread::workerThread): Pass the ContentSecurityPolicyResponseHeaders object from the start up data struct
+        to DedicatedWorkerThread::createWorkerGlobalScope().
+        * workers/WorkerThread.h:
+
 2016-01-31  Darin Adler  <darin@apple.com>
 
         Get rid of most calls to String::upper; mostly replace them with convertToASCIIUppercase
index ab7433f..37c8cd6 100644 (file)
     <ClCompile Include="..\page\Chrome.cpp" />
     <ClCompile Include="..\page\animation\CompositeAnimation.cpp" />
     <ClCompile Include="..\page\csp\ContentSecurityPolicy.cpp" />
+    <ClCompile Include="..\page\csp\ContentSecurityPolicyResponseHeaders.cpp" />
     <ClCompile Include="..\page\ContextMenuContext.cpp" />
     <ClCompile Include="..\page\ContextMenuController.cpp" />
     <ClCompile Include="..\page\Crypto.cpp" />
     <ClInclude Include="..\page\ChromeClient.h" />
     <ClInclude Include="..\page\animation\CompositeAnimation.h" />
     <ClInclude Include="..\page\csp\ContentSecurityPolicy.h" />
+    <ClInclude Include="..\page\csp\ContentSecurityPolicyResponseHeaders.h" />
     <ClInclude Include="..\page\ContextMenuClient.h" />
     <ClInclude Include="..\page\ContextMenuContext.h" />
     <ClInclude Include="..\page\ContextMenuController.h" />
index d259b27..591fee8 100644 (file)
     <ClCompile Include="..\page\csp\ContentSecurityPolicy.cpp">
       <Filter>page\csp</Filter>
     </ClCompile>
+    <ClCompile Include="..\page\csp\ContentSecurityPolicyResponseHeaders.cpp">
+      <Filter>page\csp</Filter>
+    </ClCompile>
     <ClCompile Include="..\page\ContextMenuController.cpp">
       <Filter>page</Filter>
     </ClCompile>
     <ClInclude Include="..\page\csp\ContentSecurityPolicy.h">
       <Filter>page\csp</Filter>
     </ClInclude>
+    <ClInclude Include="..\page\csp\ContentSecurityPolicyResponseHeaders.h">
+      <Filter>page\csp</Filter>
+    </ClInclude>
     <ClInclude Include="..\page\ContextMenuClient.h">
       <Filter>page</Filter>
     </ClInclude>
index 84289cf..62f308a 100644 (file)
                CE1252531A1BEC0600864480 /* NSStringSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252521A1BEC0600864480 /* NSStringSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CE1252551A1BEC0E00864480 /* NSURLDownloadSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1252541A1BEC0E00864480 /* NSURLDownloadSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CE12525B1A1C018200864480 /* CFNetworkSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE12525A1A1C018200864480 /* CFNetworkSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               CE6DADF91C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE6DADF71C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp */; };
+               CE6DADFA1C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = CE6DADF81C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h */; };
                CE7B2DB31586ABAD0098B3FA /* AlternativeTextUIController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DAF1586ABAD0098B3FA /* AlternativeTextUIController.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CE7B2DB41586ABAD0098B3FA /* AlternativeTextUIController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */; };
                CE7B2DB51586ABAD0098B3FA /* TextAlternativeWithRange.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CE12525A1A1C018200864480 /* CFNetworkSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFNetworkSPI.h; sourceTree = "<group>"; };
                CE5CB1B314EDAB6F00BB2795 /* EventSender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventSender.h; sourceTree = "<group>"; };
                CE6D89294C7AACE0AD89B3DD /* MathMLMencloseElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLMencloseElement.h; sourceTree = "<group>"; };
+               CE6DADF71C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContentSecurityPolicyResponseHeaders.cpp; path = csp/ContentSecurityPolicyResponseHeaders.cpp; sourceTree = "<group>"; };
+               CE6DADF81C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicyResponseHeaders.h; path = csp/ContentSecurityPolicyResponseHeaders.h; sourceTree = "<group>"; };
                CE7B2DAF1586ABAD0098B3FA /* AlternativeTextUIController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlternativeTextUIController.h; sourceTree = "<group>"; };
                CE7B2DB01586ABAD0098B3FA /* AlternativeTextUIController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AlternativeTextUIController.mm; sourceTree = "<group>"; };
                CE7B2DB11586ABAD0098B3FA /* TextAlternativeWithRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextAlternativeWithRange.h; sourceTree = "<group>"; };
                        children = (
                                97C471D912F925BC0086354B /* ContentSecurityPolicy.cpp */,
                                97C471DA12F925BD0086354B /* ContentSecurityPolicy.h */,
+                               CE6DADF71C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp */,
+                               CE6DADF81C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h */,
                        );
                        name = csp;
                        sourceTree = "<group>";
                                5CDFA6C81AA4F2DA00EA8746 /* ContentExtensionActions.h in Headers */,
                                7C93F34E1AA6BF0700A98BAB /* ContentExtensionCompiler.h in Headers */,
                                7CFDC57D1AC1D80500E24A57 /* ContentExtensionError.h in Headers */,
+                               CE6DADFA1C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.h in Headers */,
                                26F0C8981A2E724B002794F8 /* ContentExtensionParser.h in Headers */,
                                26F0C89C1A2EC110002794F8 /* ContentExtensionRule.h in Headers */,
                                26F0C8A01A2EC3BE002794F8 /* ContentExtensionsBackend.h in Headers */,
                                7C48A6D0191C9D6500026674 /* WebKitNamespace.cpp in Sources */,
                                A5DEBDA316FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.cpp in Sources */,
                                31C0FF240E4CEB6E007D6FE5 /* WebKitTransitionEvent.cpp in Sources */,
+                               CE6DADF91C591E6A003F6A88 /* ContentSecurityPolicyResponseHeaders.cpp in Sources */,
                                0FCF332E0F2B9A25004B6795 /* WebLayer.mm in Sources */,
                                0709D78E1AE55554004E42F8 /* WebMediaSessionManager.cpp in Sources */,
                                0709D7921AE5557E004E42F8 /* WebMediaSessionManagerMac.cpp in Sources */,
index a00932f..eb50e82 100644 (file)
@@ -3258,19 +3258,19 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
         break;
 
     case HTTPHeaderName::ContentSecurityPolicy:
-        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Enforce);
+        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderType::Enforce);
         break;
 
     case HTTPHeaderName::ContentSecurityPolicyReportOnly:
-        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Report);
+        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderType::Report);
         break;
 
     case HTTPHeaderName::XWebKitCSP:
-        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::PrefixedEnforce);
+        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderType::PrefixedEnforce);
         break;
 
     case HTTPHeaderName::XWebKitCSPReportOnly:
-        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::PrefixedReport);
+        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderType::PrefixedReport);
         break;
 
     default:
index 324bd52..eaa1c62 100644 (file)
@@ -685,21 +685,7 @@ void FrameLoader::didBeginDocument(bool dispatch)
         if (!dnsPrefetchControl.isEmpty())
             m_frame.document()->parseDNSPrefetchControlHeader(dnsPrefetchControl);
 
-        String policyValue = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ContentSecurityPolicy);
-        if (!policyValue.isEmpty())
-            m_frame.document()->contentSecurityPolicy()->didReceiveHeader(policyValue, ContentSecurityPolicy::Enforce);
-
-        policyValue = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ContentSecurityPolicyReportOnly);
-        if (!policyValue.isEmpty())
-            m_frame.document()->contentSecurityPolicy()->didReceiveHeader(policyValue, ContentSecurityPolicy::Report);
-
-        policyValue = m_documentLoader->response().httpHeaderField(HTTPHeaderName::XWebKitCSP);
-        if (!policyValue.isEmpty())
-            m_frame.document()->contentSecurityPolicy()->didReceiveHeader(policyValue, ContentSecurityPolicy::PrefixedEnforce);
-
-        policyValue = m_documentLoader->response().httpHeaderField(HTTPHeaderName::XWebKitCSPReportOnly);
-        if (!policyValue.isEmpty())
-            m_frame.document()->contentSecurityPolicy()->didReceiveHeader(policyValue, ContentSecurityPolicy::PrefixedReport);
+        m_frame.document()->contentSecurityPolicy()->didReceiveHeaders(ContentSecurityPolicyResponseHeaders(m_documentLoader->response()));
 
         String headerContentLanguage = m_documentLoader->response().httpHeaderField(HTTPHeaderName::ContentLanguage);
         if (!headerContentLanguage.isEmpty()) {
index 9f112f0..5965dbf 100644 (file)
@@ -771,11 +771,11 @@ private:
 class CSPDirectiveList {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static std::unique_ptr<CSPDirectiveList> create(ContentSecurityPolicy*, const String&, ContentSecurityPolicy::HeaderType);
-    CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType);
+    static std::unique_ptr<CSPDirectiveList> create(ContentSecurityPolicy*, const String&, ContentSecurityPolicyHeaderType);
+    CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicyHeaderType);
 
     const String& header() const { return m_header; }
-    ContentSecurityPolicy::HeaderType headerType() const { return m_headerType; }
+    ContentSecurityPolicyHeaderType headerType() const { return m_headerType; }
 
     bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
     bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
@@ -835,7 +835,7 @@ private:
     ContentSecurityPolicy* m_policy;
 
     String m_header;
-    ContentSecurityPolicy::HeaderType m_headerType;
+    ContentSecurityPolicyHeaderType m_headerType;
 
     bool m_reportOnly;
     bool m_haveSandboxPolicy;
@@ -859,17 +859,17 @@ private:
     String m_evalDisabledErrorMessage;
 };
 
-CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicy::HeaderType type)
+CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicyHeaderType type)
     : m_policy(policy)
     , m_headerType(type)
     , m_reportOnly(false)
     , m_haveSandboxPolicy(false)
     , m_reflectedXSSDisposition(ContentSecurityPolicy::ReflectedXSSUnset)
 {
-    m_reportOnly = (type == ContentSecurityPolicy::Report || type == ContentSecurityPolicy::PrefixedReport);
+    m_reportOnly = (type == ContentSecurityPolicyHeaderType::Report || type == ContentSecurityPolicyHeaderType::PrefixedReport);
 }
 
-std::unique_ptr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const String& header, ContentSecurityPolicy::HeaderType type)
+std::unique_ptr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const String& header, ContentSecurityPolicyHeaderType type)
 {
     auto directives = std::make_unique<CSPDirectiveList>(policy, type);
     directives->parse(header);
@@ -1371,7 +1371,22 @@ void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other)
         didReceiveHeader(policy->header(), policy->headerType());
 }
 
-void ContentSecurityPolicy::didReceiveHeader(const String& header, HeaderType type)
+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;
+}
+
+void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers)
+{
+    for (auto& header : headers.m_headers)
+        didReceiveHeader(header.first, header.second);
+}
+
+void ContentSecurityPolicy::didReceiveHeader(const String& header, ContentSecurityPolicyHeaderType type)
 {
     // RFC2616, section 4.2 specifies that headers appearing multiple times can
     // be combined with a comma. Walk the header string, and parse each comma
@@ -1403,16 +1418,6 @@ void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
     m_overrideInlineStyleAllowed = value;
 }
 
-const String& ContentSecurityPolicy::deprecatedHeader() const
-{
-    return m_policies.isEmpty() ? emptyString() : m_policies[0]->header();
-}
-
-ContentSecurityPolicy::HeaderType ContentSecurityPolicy::deprecatedHeaderType() const
-{
-    return m_policies.isEmpty() ? Enforce : m_policies[0]->headerType();
-}
-
 template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
 bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus)
 {
index cedf1e2..ab3cb34 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef ContentSecurityPolicy_h
 #define ContentSecurityPolicy_h
 
+#include "ContentSecurityPolicyResponseHeaders.h"
 #include "URL.h"
 #include "ScriptState.h"
 #include <memory>
@@ -56,13 +57,6 @@ public:
 
     void copyStateFrom(const ContentSecurityPolicy*);
 
-    enum HeaderType {
-        Report,
-        Enforce,
-        PrefixedReport,
-        PrefixedEnforce
-    };
-
     enum class ReportingStatus {
         SendReport,
         SuppressReport
@@ -77,12 +71,9 @@ public:
         BlockReflectedXSS
     };
 
-    void didReceiveHeader(const String&, HeaderType);
-
-    // These functions are wrong because they assume that there is only one header.
-    // FIXME: Replace them with functions that return vectors.
-    const String& deprecatedHeader() const;
-    HeaderType deprecatedHeaderType() const;
+    ContentSecurityPolicyResponseHeaders responseHeaders() const;
+    void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&);
+    void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType);
 
     bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
     bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy = false, ContentSecurityPolicy::ReportingStatus = ContentSecurityPolicy::ReportingStatus::SendReport) const;
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.cpp b/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.cpp
new file mode 100644 (file)
index 0000000..0b67b91
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ContentSecurityPolicyResponseHeaders.h"
+
+#include "HTTPHeaderNames.h"
+#include "ResourceResponse.h"
+
+namespace WebCore {
+
+ContentSecurityPolicyResponseHeaders::ContentSecurityPolicyResponseHeaders(const ResourceResponse& response)
+{
+    String policyValue = response.httpHeaderField(HTTPHeaderName::ContentSecurityPolicy);
+    if (!policyValue.isEmpty())
+        m_headers.append({ policyValue, ContentSecurityPolicyHeaderType::Enforce });
+
+    policyValue = response.httpHeaderField(HTTPHeaderName::ContentSecurityPolicyReportOnly);
+    if (!policyValue.isEmpty())
+        m_headers.append({ policyValue, ContentSecurityPolicyHeaderType::Report });
+
+    policyValue = response.httpHeaderField(HTTPHeaderName::XWebKitCSP);
+    if (!policyValue.isEmpty())
+        m_headers.append({ policyValue, ContentSecurityPolicyHeaderType::PrefixedEnforce });
+
+    policyValue = response.httpHeaderField(HTTPHeaderName::XWebKitCSPReportOnly);
+    if (!policyValue.isEmpty())
+        m_headers.append({ policyValue, ContentSecurityPolicyHeaderType::PrefixedReport });
+}
+
+ContentSecurityPolicyResponseHeaders ContentSecurityPolicyResponseHeaders::isolatedCopy() const
+{
+    ContentSecurityPolicyResponseHeaders isolatedCopy;
+    isolatedCopy.m_headers.reserveInitialCapacity(m_headers.size());
+    for (auto& header : m_headers)
+        isolatedCopy.m_headers.uncheckedAppend({ header.first.isolatedCopy(), header.second });
+    return isolatedCopy;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h b/Source/WebCore/page/csp/ContentSecurityPolicyResponseHeaders.h
new file mode 100644 (file)
index 0000000..50c7c4a
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ContentSecurityPolicyResponseHeaders_h
+#define ContentSecurityPolicyResponseHeaders_h
+
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+class ResourceResponse;
+
+enum class ContentSecurityPolicyHeaderType {
+    Report,
+    Enforce,
+    PrefixedReport,
+    PrefixedEnforce,
+};
+
+class ContentSecurityPolicyResponseHeaders {
+public:
+    ContentSecurityPolicyResponseHeaders(const ResourceResponse&);
+
+    ContentSecurityPolicyResponseHeaders isolatedCopy() const;
+
+private:
+    friend class ContentSecurityPolicy;
+
+    ContentSecurityPolicyResponseHeaders() = default;
+
+    Vector<std::pair<String, ContentSecurityPolicyHeaderType>> m_headers;
+};
+
+} // namespace WebCore
+
+#endif /* ContentSecurityPolicyResponseHeaders_h */
index 15f014e..91c7f23 100644 (file)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "DedicatedWorkerGlobalScope.h"
 
+#include "ContentSecurityPolicyResponseHeaders.h"
 #include "DOMWindow.h"
 #include "DedicatedWorkerThread.h"
 #include "MessageEvent.h"
 
 namespace WebCore {
 
-Ref<DedicatedWorkerGlobalScope> DedicatedWorkerGlobalScope::create(const URL& url, const String& userAgent, DedicatedWorkerThread& thread, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, PassRefPtr<SecurityOrigin> topOrigin)
+Ref<DedicatedWorkerGlobalScope> DedicatedWorkerGlobalScope::create(const URL& url, const String& userAgent, DedicatedWorkerThread& thread, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, PassRefPtr<SecurityOrigin> topOrigin)
 {
     Ref<DedicatedWorkerGlobalScope> context = adoptRef(*new DedicatedWorkerGlobalScope(url, userAgent, thread, topOrigin));
-    context->applyContentSecurityPolicyFromString(contentSecurityPolicy, contentSecurityPolicyType);
+    context->applyContentSecurityPolicyResponseHeaders(contentSecurityPolicyResponseHeaders);
     return context;
 }
 
index f1fd969..29b722a 100644 (file)
 #ifndef DedicatedWorkerGlobalScope_h
 #define DedicatedWorkerGlobalScope_h
 
-#include "ContentSecurityPolicy.h"
 #include "MessagePort.h"
 #include "WorkerGlobalScope.h"
 
 namespace WebCore {
 
+    class ContentSecurityPolicyResponseHeaders;
     class DedicatedWorkerThread;
 
     class DedicatedWorkerGlobalScope : public WorkerGlobalScope {
     public:
         typedef WorkerGlobalScope Base;
-        static Ref<DedicatedWorkerGlobalScope> create(const URL&, const String& userAgent, DedicatedWorkerThread&, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, PassRefPtr<SecurityOrigin> topOrigin);
+        static Ref<DedicatedWorkerGlobalScope> create(const URL&, const String& userAgent, DedicatedWorkerThread&, const ContentSecurityPolicyResponseHeaders&, PassRefPtr<SecurityOrigin> topOrigin);
         virtual ~DedicatedWorkerGlobalScope();
 
         virtual bool isDedicatedWorkerGlobalScope() const override { return true; }
index 19005cb..3604bf8 100644 (file)
@@ -38,8 +38,8 @@
 
 namespace WebCore {
 
-DedicatedWorkerThread::DedicatedWorkerThread(const URL& url, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, const SecurityOrigin* topOrigin)
-    : WorkerThread(url, userAgent, sourceCode, workerLoaderProxy, workerObjectProxy, startMode, contentSecurityPolicy, contentSecurityPolicyType, topOrigin)
+DedicatedWorkerThread::DedicatedWorkerThread(const URL& url, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, const SecurityOrigin* topOrigin)
+    : WorkerThread(url, userAgent, sourceCode, workerLoaderProxy, workerObjectProxy, startMode, contentSecurityPolicyResponseHeaders, topOrigin)
     , m_workerObjectProxy(workerObjectProxy)
 {
 }
@@ -48,9 +48,9 @@ DedicatedWorkerThread::~DedicatedWorkerThread()
 {
 }
 
-Ref<WorkerGlobalScope> DedicatedWorkerThread::createWorkerGlobalScope(const URL& url, const String& userAgent, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, PassRefPtr<SecurityOrigin> topOrigin)
+Ref<WorkerGlobalScope> DedicatedWorkerThread::createWorkerGlobalScope(const URL& url, const String& userAgent, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, PassRefPtr<SecurityOrigin> topOrigin)
 {
-    return DedicatedWorkerGlobalScope::create(url, userAgent, *this, contentSecurityPolicy, contentSecurityPolicyType, topOrigin);
+    return DedicatedWorkerGlobalScope::create(url, userAgent, *this, contentSecurityPolicyResponseHeaders, topOrigin);
 }
 
 void DedicatedWorkerThread::runEventLoop()
index cc10108..89d88f2 100644 (file)
 #ifndef DedicatedWorkerThread_h
 #define DedicatedWorkerThread_h
 
-#include "ContentSecurityPolicy.h"
 #include "WorkerThread.h"
 
 namespace WebCore {
 
+    class ContentSecurityPolicyResponseHeaders;
     class WorkerObjectProxy;
 
     class DedicatedWorkerThread : public WorkerThread {
@@ -48,11 +48,11 @@ namespace WebCore {
         WorkerObjectProxy& workerObjectProxy() const { return m_workerObjectProxy; }
 
     protected:
-        virtual Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& userAgent, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType, PassRefPtr<SecurityOrigin> topOrigin) override;
+        virtual Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& userAgent, const ContentSecurityPolicyResponseHeaders&, PassRefPtr<SecurityOrigin> topOrigin) override;
         virtual void runEventLoop() override;
 
     private:
-        DedicatedWorkerThread(const URL&, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerObjectProxy&, WorkerThreadStartMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType, const SecurityOrigin* topOrigin);
+        DedicatedWorkerThread(const URL&, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerObjectProxy&, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, const SecurityOrigin* topOrigin);
 
         WorkerObjectProxy& m_workerObjectProxy;
     };
index 41f0a5b..910dd8b 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "DOMWindow.h"
 #include "CachedResourceLoader.h"
+#include "ContentSecurityPolicy.h"
 #include "Document.h"
 #include "EventListener.h"
 #include "EventNames.h"
@@ -40,6 +41,7 @@
 #include "InspectorInstrumentation.h"
 #include "MessageEvent.h"
 #include "NetworkStateNotifier.h"
+#include "SecurityOrigin.h"
 #include "TextEncoding.h"
 #include "WorkerGlobalScopeProxy.h"
 #include "WorkerScriptLoader.h"
@@ -150,8 +152,11 @@ void Worker::notifyNetworkStateChange(bool isOnLine)
     m_contextProxy->notifyNetworkStateChange(isOnLine);
 }
 
-void Worker::didReceiveResponse(unsigned long identifier, const ResourceResponse&)
+void Worker::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
 {
+    const URL& responseURL = response.url();
+    if (!responseURL.protocolIs("blob") && !responseURL.protocolIs("file") && !SecurityOrigin::create(responseURL)->isUnique())
+        m_contentSecurityPolicyResponseHeaders = ContentSecurityPolicyResponseHeaders(response);
     InspectorInstrumentation::didReceiveScriptResponse(scriptExecutionContext(), identifier);
 }
 
@@ -160,8 +165,8 @@ void Worker::notifyFinished()
     if (m_scriptLoader->failed())
         dispatchEvent(Event::create(eventNames().errorEvent, false, true));
     else {
-        WorkerThreadStartMode startMode = DontPauseWorkerGlobalScopeOnStart;
-        m_contextProxy->startWorkerGlobalScope(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), startMode);
+        const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders = m_contentSecurityPolicyResponseHeaders ? m_contentSecurityPolicyResponseHeaders.value() : scriptExecutionContext()->contentSecurityPolicy()->responseHeaders();
+        m_contextProxy->startWorkerGlobalScope(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), contentSecurityPolicyResponseHeaders, DontPauseWorkerGlobalScopeOnStart);
         InspectorInstrumentation::scriptImported(scriptExecutionContext(), m_scriptLoader->identifier(), m_scriptLoader->script());
     }
     m_scriptLoader = nullptr;
index 0985751..cd3d111 100644 (file)
 
 #include "AbstractWorker.h"
 #include "ActiveDOMObject.h"
+#include "ContentSecurityPolicyResponseHeaders.h"
 #include "EventListener.h"
 #include "EventTarget.h"
 #include "MessagePort.h"
 #include "WorkerScriptLoaderClient.h"
 #include <wtf/Forward.h>
+#include <wtf/Optional.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
 #include <wtf/text/AtomicStringHash.h>
@@ -83,6 +85,7 @@ namespace WebCore {
 
         RefPtr<WorkerScriptLoader> m_scriptLoader;
         WorkerGlobalScopeProxy* m_contextProxy; // The proxy outlives the worker to perform thread shutdown.
+        Optional<ContentSecurityPolicyResponseHeaders> m_contentSecurityPolicyResponseHeaders;
     };
 
 } // namespace WebCore
index 3027a52..c6fcf2d 100644 (file)
@@ -85,10 +85,10 @@ WorkerGlobalScope::~WorkerGlobalScope()
     thread().workerReportingProxy().workerGlobalScopeDestroyed();
 }
 
-void WorkerGlobalScope::applyContentSecurityPolicyFromString(const String& policy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType)
+void WorkerGlobalScope::applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders)
 {
     setContentSecurityPolicy(std::make_unique<ContentSecurityPolicy>(this));
-    contentSecurityPolicy()->didReceiveHeader(policy, contentSecurityPolicyType);
+    contentSecurityPolicy()->didReceiveHeaders(contentSecurityPolicyResponseHeaders);
 }
 
 URL WorkerGlobalScope::completeURL(const String& url) const
index 2acefce..d4db351 100644 (file)
@@ -27,7 +27,6 @@
 #ifndef WorkerGlobalScope_h
 #define WorkerGlobalScope_h
 
-#include "ContentSecurityPolicy.h"
 #include "EventListener.h"
 #include "EventTarget.h"
 #include "ScriptExecutionContext.h"
@@ -45,6 +44,7 @@
 namespace WebCore {
 
     class Blob;
+    class ContentSecurityPolicyResponseHeaders;
     class ScheduledAction;
     class WorkerLocation;
     class WorkerNavigator;
@@ -131,7 +131,7 @@ namespace WebCore {
 
     protected:
         WorkerGlobalScope(const URL&, const String& userAgent, WorkerThread&, PassRefPtr<SecurityOrigin> topOrigin);
-        void applyContentSecurityPolicyFromString(const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType);
+        void applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders&);
 
         virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, RefPtr<Inspector::ScriptCallStack>&&) override;
         void addMessageToWorkerConsole(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, RefPtr<Inspector::ScriptCallStack>&&, JSC::ExecState* = 0, unsigned long requestIdentifier = 0);
index f5fbf4f..6bd88c4 100644 (file)
@@ -38,6 +38,7 @@
 
 namespace WebCore {
 
+    class ContentSecurityPolicyResponseHeaders;
     class URL;
     class Worker;
 
@@ -48,7 +49,7 @@ namespace WebCore {
 
         virtual ~WorkerGlobalScopeProxy() { }
 
-        virtual void startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode) = 0;
+        virtual void startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, WorkerThreadStartMode) = 0;
 
         virtual void terminateWorkerGlobalScope() = 0;
 
index 8456abb..699e9b7 100644 (file)
@@ -72,12 +72,12 @@ WorkerMessagingProxy::~WorkerMessagingProxy()
         || (is<WorkerGlobalScope>(*m_scriptExecutionContext) && currentThread() == downcast<WorkerGlobalScope>(*m_scriptExecutionContext).thread().threadID()));
 }
 
-void WorkerMessagingProxy::startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode)
+void WorkerMessagingProxy::startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, WorkerThreadStartMode startMode)
 {
     // FIXME: This need to be revisited when we support nested worker one day
     ASSERT(m_scriptExecutionContext);
     Document& document = downcast<Document>(*m_scriptExecutionContext);
-    RefPtr<DedicatedWorkerThread> thread = DedicatedWorkerThread::create(scriptURL, userAgent, sourceCode, *this, *this, startMode, document.contentSecurityPolicy()->deprecatedHeader(), document.contentSecurityPolicy()->deprecatedHeaderType(), document.topOrigin());
+    RefPtr<DedicatedWorkerThread> thread = DedicatedWorkerThread::create(scriptURL, userAgent, sourceCode, *this, *this, startMode, contentSecurityPolicyResponseHeaders, document.topOrigin());
     workerThreadCreated(thread);
     thread->start();
 }
index eb7af58..aa5b891 100644 (file)
@@ -40,6 +40,7 @@
 
 namespace WebCore {
 
+    class ContentSecurityPolicyResponseHeaders;
     class DedicatedWorkerThread;
     class ScriptExecutionContext;
     class Worker;
@@ -51,7 +52,7 @@ namespace WebCore {
 
         // Implementations of WorkerGlobalScopeProxy.
         // (Only use these methods in the worker object thread.)
-        virtual void startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode) override;
+        virtual void startWorkerGlobalScope(const URL& scriptURL, const String& userAgent, const String& sourceCode, const ContentSecurityPolicyResponseHeaders&, WorkerThreadStartMode) override;
         virtual void terminateWorkerGlobalScope() override;
         virtual void postMessageToWorkerGlobalScope(PassRefPtr<SerializedScriptValue>, std::unique_ptr<MessagePortChannelArray>) override;
         virtual bool hasPendingActivity() const override;
index c77ea9c..8122380 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "WorkerThread.h"
 
+#include "ContentSecurityPolicyResponseHeaders.h"
 #include "DedicatedWorkerGlobalScope.h"
 #include "ScriptSourceCode.h"
 #include "SecurityOrigin.h"
@@ -69,33 +70,31 @@ unsigned WorkerThread::workerThreadCount()
 struct WorkerThreadStartupData {
     WTF_MAKE_NONCOPYABLE(WorkerThreadStartupData); WTF_MAKE_FAST_ALLOCATED;
 public:
-    WorkerThreadStartupData(const URL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, const SecurityOrigin* topOrigin);
+    WorkerThreadStartupData(const URL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, const SecurityOrigin* topOrigin);
 
     URL m_scriptURL;
     String m_userAgent;
     String m_sourceCode;
     WorkerThreadStartMode m_startMode;
-    String m_contentSecurityPolicy;
-    ContentSecurityPolicy::HeaderType m_contentSecurityPolicyType;
+    ContentSecurityPolicyResponseHeaders m_contentSecurityPolicyResponseHeaders;
     RefPtr<SecurityOrigin> m_topOrigin;
 };
 
-WorkerThreadStartupData::WorkerThreadStartupData(const URL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, const SecurityOrigin* topOrigin)
+WorkerThreadStartupData::WorkerThreadStartupData(const URL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, const SecurityOrigin* topOrigin)
     : m_scriptURL(scriptURL.isolatedCopy())
     , m_userAgent(userAgent.isolatedCopy())
     , m_sourceCode(sourceCode.isolatedCopy())
     , m_startMode(startMode)
-    , m_contentSecurityPolicy(contentSecurityPolicy.isolatedCopy())
-    , m_contentSecurityPolicyType(contentSecurityPolicyType)
+    , m_contentSecurityPolicyResponseHeaders(contentSecurityPolicyResponseHeaders.isolatedCopy())
     , m_topOrigin(topOrigin ? &topOrigin->isolatedCopy().get() : nullptr)
 {
 }
 
-WorkerThread::WorkerThread(const URL& scriptURL, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, const SecurityOrigin* topOrigin)
+WorkerThread::WorkerThread(const URL& scriptURL, const String& userAgent, const String& sourceCode, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicyResponseHeaders, const SecurityOrigin* topOrigin)
     : m_threadID(0)
     , m_workerLoaderProxy(workerLoaderProxy)
     , m_workerReportingProxy(workerReportingProxy)
-    , m_startupData(std::make_unique<WorkerThreadStartupData>(scriptURL, userAgent, sourceCode, startMode, contentSecurityPolicy, contentSecurityPolicyType, topOrigin))
+    , m_startupData(std::make_unique<WorkerThreadStartupData>(scriptURL, userAgent, sourceCode, startMode, contentSecurityPolicyResponseHeaders, topOrigin))
 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
     , m_notificationClient(0)
 #endif
@@ -145,7 +144,7 @@ void WorkerThread::workerThread()
 
     {
         LockHolder lock(m_threadCreationMutex);
-        m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_userAgent, m_startupData->m_contentSecurityPolicy, m_startupData->m_contentSecurityPolicyType, m_startupData->m_topOrigin.release());
+        m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_userAgent, m_startupData->m_contentSecurityPolicyResponseHeaders, m_startupData->m_topOrigin.release());
 
         if (m_runLoop.terminated()) {
             // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
index 627baae..bb79582 100644 (file)
@@ -27,7 +27,6 @@
 #ifndef WorkerThread_h
 #define WorkerThread_h
 
-#include "ContentSecurityPolicy.h"
 #include "WorkerRunLoop.h"
 #include <memory>
 #include <wtf/Forward.h>
@@ -36,6 +35,7 @@
 
 namespace WebCore {
 
+    class ContentSecurityPolicyResponseHeaders;
     class URL;
     class NotificationClient;
     class SecurityOrigin;
@@ -68,10 +68,10 @@ namespace WebCore {
 #endif
 
     protected:
-        WorkerThread(const URL&, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerReportingProxy&, WorkerThreadStartMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType, const SecurityOrigin* topOrigin);
+        WorkerThread(const URL&, const String& userAgent, const String& sourceCode, WorkerLoaderProxy&, WorkerReportingProxy&, WorkerThreadStartMode, const ContentSecurityPolicyResponseHeaders&, const SecurityOrigin* topOrigin);
 
         // Factory method for creating a new worker context for the thread.
-        virtual Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& userAgent, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType, PassRefPtr<SecurityOrigin> topOrigin) = 0;
+        virtual Ref<WorkerGlobalScope> createWorkerGlobalScope(const URL&, const String& userAgent, const ContentSecurityPolicyResponseHeaders&, PassRefPtr<SecurityOrigin> topOrigin) = 0;
 
         // Executes the event loop for the worker thread. Derived classes can override to perform actions before/after entering the event loop.
         virtual void runEventLoop();