Title: [250255] trunk
Revision
250255
Author
dba...@webkit.org
Date
2019-09-23 14:56:43 -0700 (Mon, 23 Sep 2019)

Log Message

Improve CSP inheritance semantics
https://bugs.webkit.org/show_bug.cgi?id=201884
<rdar://problem/50172407>

Reviewed by Brent Fulgham.

LayoutTests/imported/w3c:

Update expected results now that we pass more sub-tests.

* web-platform-tests/content-security-policy/inheritance/iframe-all-local-schemes-inherit-self.sub-expected.txt:
* web-platform-tests/content-security-policy/inheritance/window-expected.txt:

Source/WebCore:

Update the CSP inheritance semantics to more closely match the logic in section Initialize a Document's CSP list
of the CSP3 spec., <https://w3c.github.io/webappsec-csp/#initialize-document-csp>.

Towards this, move more of the inheritance logic out of Document::initContentSecurityPolicy() and into
DocumentWriter::begin() where details about the document being replaced live. This lets us remove the
need to track the previous content security policy to pass it to Document::initContentSecurityPolicy().
Moreover, DocumentWriter::begin() knows the owner document that will be replaced with the result of
executing a _javascript_ URL. This is needed in order to fix up inheritance of CSP for such documents.

Tests: http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url.html
       http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url.html
       http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2.html

* dom/Document.cpp:
(WebCore::Document::initSecurityContext): If we are inheriting the security origin from the owner
document then inherit its CSP policy. We copy over both the CSP state from the owner as well as
update 'self' to match the owner's origin so that CSP source expressions that include 'self' work
correctly even from about:blank documents.
(WebCore::Document::initContentSecurityPolicy): Move most of the logic from here into DocumentWriter::begin()
to take advantage of the fact that DocumentWriter::begin() knows about the outgoing document (if there
is one) as well as whether the outgoing document is being replaced with a new document that is the result
of evaluating a _javascript_ URL. We need do know both these things in order to inherit the correct CSP
policy. This function only exists to copy some upgrade-insecure-requests state and to fix up plugin documents
as we currently do.
(WebCore::Document::shouldInheritContentSecurityPolicy const): Deleted.
* dom/Document.h:
* dom/SecurityContext.cpp:
(WebCore::SecurityContext::setContentSecurityPolicy): Modified to take its param by rvalue-reference
to make it less error prone to use.
* dom/SecurityContext.h: Expose setContentSecurityPolicy() so that we can invoke it from DocumentWriter::begin().
* loader/DocumentWriter.cpp:
(WebCore::DocumentWriter::begin): For documents being replaced with the result of a _javascript_ URL (i.e. ownerDocument
is non-null) inherit the CSP from the owner document. Similarly, if we have an existing document in the frame
and the protocol of the new document's URL is data: or blob: then inherit the CSP from the existing page. The latter
is what we currently do just moved from Document::initContentSecurityPolicy() and re-written in terms of the
existingDocument instead of previousContentSecurityPolicy. Also call setInsecureNavigationRequestsToUpgrade()
both when we have a non-null ownerDocument as well as when we have a non-null existingDocument. The former fixes
the block-all-mixed-content feature for documents loaded via _javascript_ URLs and the latter is what we do now.
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::didBeginDocument): Remove parameter previousContentSecurityPolicy as the logic that
made use of it moved to DocumentWriter::begin().
* loader/FrameLoader.h:
* page/csp/ContentSecurityPolicy.h:

LayoutTests:

Add some more tests and update expected results of existing tests now that we pass more sub-tests.

* http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url.html: Added.
* http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url.html: Added.
* http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2.html: Added.
* http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt: I don't understand
why there is another duplicte console log message emitted, but there are already two such messages, which is
already one too many. The duplicate messages are more cosmetic than functional though there may be implications
with respect to CSP reporting. Filed <https://bugs.webkit.org/show_bug.cgi?id=202004> to track this issue.
* platform/mac-wk1/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt:
* platform/win/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (250254 => 250255)


--- trunk/LayoutTests/ChangeLog	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/LayoutTests/ChangeLog	2019-09-23 21:56:43 UTC (rev 250255)
@@ -1,3 +1,26 @@
+2019-09-23  Daniel Bates  <daba...@apple.com>
+
+        Improve CSP inheritance semantics
+        https://bugs.webkit.org/show_bug.cgi?id=201884
+        <rdar://problem/50172407>
+
+        Reviewed by Brent Fulgham.
+
+        Add some more tests and update expected results of existing tests now that we pass more sub-tests.
+
+        * http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url.html: Added.
+        * http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url.html: Added.
+        * http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2.html: Added.
+        * http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt: I don't understand
+        why there is another duplicte console log message emitted, but there are already two such messages, which is
+        already one too many. The duplicate messages are more cosmetic than functional though there may be implications
+        with respect to CSP reporting. Filed <https://bugs.webkit.org/show_bug.cgi?id=202004> to track this issue.
+        * platform/mac-wk1/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt:
+        * platform/win/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt:
+
 2019-09-16  Jiewen Tan  <jiewen_...@apple.com>
 
         [WebAuthn] LocalAuthenticator tests are failing on internal bots

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url-expected.txt (0 => 250255)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url-expected.txt	2019-09-23 21:56:43 UTC (rev 250255)
@@ -0,0 +1,7 @@
+ALERT: PASS
+
+
+--------
+Frame: '<!--frame1-->'
+--------
+

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url.html (0 => 250255)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url.html	2019-09-23 21:56:43 UTC (rev 250255)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'; child-src http://localhost:8000">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpChildFramesAsText();
+    testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<script>
+var test = "_javascript_:'<iframe src="" && window.setTimeout(() => testRunner.notifyDone(), 0);</" + "script>'";
+window.open(test, "_self");
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url-expected.txt (0 => 250255)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url-expected.txt	2019-09-23 21:56:43 UTC (rev 250255)
@@ -0,0 +1,7 @@
+CONSOLE MESSAGE: Refused to load http://localhost:8000/security/contentSecurityPolicy/resources/alert-fail.html because it appears in neither the child-src directive nor the default-src directive of the Content Security Policy.
+
+
+--------
+Frame: '<!--frame1-->'
+--------
+

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url.html (0 => 250255)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url.html	2019-09-23 21:56:43 UTC (rev 250255)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpChildFramesAsText();
+    testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<script>
+var test = "_javascript_:'<iframe src="" && window.setTimeout(() => testRunner.notifyDone(), 0);</" + "script>'";
+window.open(test, "_self");
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2-expected.txt (0 => 250255)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2-expected.txt	2019-09-23 21:56:43 UTC (rev 250255)
@@ -0,0 +1,12 @@
+CONSOLE MESSAGE: Refused to load http://localhost:8000/security/contentSecurityPolicy/resources/alert-fail.html because it appears in neither the child-src directive nor the default-src directive of the Content Security Policy.
+
+
+--------
+Frame: '<!--frame1-->'
+--------
+
+
+--------
+Frame: '<!--frame2-->'
+--------
+

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2.html (0 => 250255)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2.html	2019-09-23 21:56:43 UTC (rev 250255)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.dumpChildFramesAsText();
+    testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<script>
+var test = "_javascript_:'<iframe src="" src="" && window.setTimeout(() => testRunner.notifyDone(), 0);</" + "script>`\"></iframe>'";
+window.open(test, "_self");
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt (250254 => 250255)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt	2019-09-23 21:56:43 UTC (rev 250255)
@@ -2,5 +2,7 @@
 Blocked access to external URL http://webkit.org/report
 CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
 Blocked access to external URL http://webkit.org/report
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
+Blocked access to external URL http://webkit.org/report
 The iframe below triggers a violation report creating the initial empty document. It should not crash the web process.
 

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (250254 => 250255)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2019-09-23 21:56:43 UTC (rev 250255)
@@ -1,3 +1,16 @@
+2019-09-23  Daniel Bates  <daba...@apple.com>
+
+        Improve CSP inheritance semantics
+        https://bugs.webkit.org/show_bug.cgi?id=201884
+        <rdar://problem/50172407>
+
+        Reviewed by Brent Fulgham.
+
+        Update expected results now that we pass more sub-tests.
+
+        * web-platform-tests/content-security-policy/inheritance/iframe-all-local-schemes-inherit-self.sub-expected.txt:
+        * web-platform-tests/content-security-policy/inheritance/window-expected.txt:
+
 2019-09-23  Rob Buis  <rb...@igalia.com>
 
         Sync operator dictionary

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/inheritance/iframe-all-local-schemes-inherit-self.sub-expected.txt (250254 => 250255)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/inheritance/iframe-all-local-schemes-inherit-self.sub-expected.txt	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/inheritance/iframe-all-local-schemes-inherit-self.sub-expected.txt	2019-09-23 21:56:43 UTC (rev 250255)
@@ -1,9 +1,8 @@
 
-
 PASS <iframe>'s about:blank inherits policy. 
 PASS <iframe srcdoc>'s inherits policy. 
 PASS <iframe src=''>'s inherits policy. 
-FAIL <iframe src=''>'s inherits policy. assert_equals: expected "load" but got "error"
+PASS <iframe src=''>'s inherits policy. 
 PASS <iframe src=''>'s inherits policy. 
-FAIL <iframe sandbox src=''>'s inherits policy. (opaque origin sandbox) assert_equals: expected "load" but got "error"
+PASS <iframe sandbox src=''>'s inherits policy. (opaque origin sandbox) 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/inheritance/window-expected.txt (250254 => 250255)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/inheritance/window-expected.txt	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/inheritance/window-expected.txt	2019-09-23 21:56:43 UTC (rev 250255)
@@ -1,6 +1,6 @@
 
 PASS window.open() inherits policy. 
 PASS `document.write` into `window.open()` inherits policy. 
-FAIL window.open('blob:...') inherits policy. assert_equals: expected "error" but got "load"
+PASS window.open('blob:...') inherits policy. 
 PASS window.open('_javascript_:...') inherits policy. 
 

Modified: trunk/LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt (250254 => 250255)


--- trunk/LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/LayoutTests/platform/mac-wk1/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt	2019-09-23 21:56:43 UTC (rev 250255)
@@ -1,4 +1,5 @@
 CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
 CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
 The iframe below triggers a violation report creating the initial empty document. It should not crash the web process.
 

Modified: trunk/LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt (250254 => 250255)


--- trunk/LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/LayoutTests/platform/win/http/tests/security/contentSecurityPolicy/user-style-sheet-font-crasher-expected.txt	2019-09-23 21:56:43 UTC (rev 250255)
@@ -1,4 +1,5 @@
 CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
 CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/security/contentSecurityPolicy/example_font.woff because it does not appear in the font-src directive of the Content Security Policy.
 The iframe below triggers a violation report creating the initial empty document. It should not crash the web process.
 

Modified: trunk/Source/WebCore/ChangeLog (250254 => 250255)


--- trunk/Source/WebCore/ChangeLog	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/Source/WebCore/ChangeLog	2019-09-23 21:56:43 UTC (rev 250255)
@@ -1,3 +1,55 @@
+2019-09-23  Daniel Bates  <daba...@apple.com>
+
+        Improve CSP inheritance semantics
+        https://bugs.webkit.org/show_bug.cgi?id=201884
+        <rdar://problem/50172407>
+
+        Reviewed by Brent Fulgham.
+
+        Update the CSP inheritance semantics to more closely match the logic in section Initialize a Document's CSP list
+        of the CSP3 spec., <https://w3c.github.io/webappsec-csp/#initialize-document-csp>.
+
+        Towards this, move more of the inheritance logic out of Document::initContentSecurityPolicy() and into
+        DocumentWriter::begin() where details about the document being replaced live. This lets us remove the
+        need to track the previous content security policy to pass it to Document::initContentSecurityPolicy().
+        Moreover, DocumentWriter::begin() knows the owner document that will be replaced with the result of
+        executing a _javascript_ URL. This is needed in order to fix up inheritance of CSP for such documents.
+
+        Tests: http/tests/security/contentSecurityPolicy/iframe-allowed-when-loaded-via-_javascript_-url.html
+               http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url.html
+               http/tests/security/contentSecurityPolicy/iframe-blocked-when-loaded-via-_javascript_-url2.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::initSecurityContext): If we are inheriting the security origin from the owner
+        document then inherit its CSP policy. We copy over both the CSP state from the owner as well as
+        update 'self' to match the owner's origin so that CSP source expressions that include 'self' work
+        correctly even from about:blank documents.
+        (WebCore::Document::initContentSecurityPolicy): Move most of the logic from here into DocumentWriter::begin()
+        to take advantage of the fact that DocumentWriter::begin() knows about the outgoing document (if there
+        is one) as well as whether the outgoing document is being replaced with a new document that is the result
+        of evaluating a _javascript_ URL. We need do know both these things in order to inherit the correct CSP
+        policy. This function only exists to copy some upgrade-insecure-requests state and to fix up plugin documents
+        as we currently do.
+        (WebCore::Document::shouldInheritContentSecurityPolicy const): Deleted.
+        * dom/Document.h:
+        * dom/SecurityContext.cpp:
+        (WebCore::SecurityContext::setContentSecurityPolicy): Modified to take its param by rvalue-reference
+        to make it less error prone to use.
+        * dom/SecurityContext.h: Expose setContentSecurityPolicy() so that we can invoke it from DocumentWriter::begin().
+        * loader/DocumentWriter.cpp:
+        (WebCore::DocumentWriter::begin): For documents being replaced with the result of a _javascript_ URL (i.e. ownerDocument
+        is non-null) inherit the CSP from the owner document. Similarly, if we have an existing document in the frame
+        and the protocol of the new document's URL is data: or blob: then inherit the CSP from the existing page. The latter
+        is what we currently do just moved from Document::initContentSecurityPolicy() and re-written in terms of the
+        existingDocument instead of previousContentSecurityPolicy. Also call setInsecureNavigationRequestsToUpgrade()
+        both when we have a non-null ownerDocument as well as when we have a non-null existingDocument. The former fixes
+        the block-all-mixed-content feature for documents loaded via _javascript_ URLs and the latter is what we do now.
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::didBeginDocument): Remove parameter previousContentSecurityPolicy as the logic that
+        made use of it moved to DocumentWriter::begin().
+        * loader/FrameLoader.h:
+        * page/csp/ContentSecurityPolicy.h:
+
 2019-09-23  Keith Rollin  <krol...@apple.com>
 
         Unreviewed build fix after r250173: tvOS build broken due to unused function.

Modified: trunk/Source/WebCore/dom/Document.cpp (250254 => 250255)


--- trunk/Source/WebCore/dom/Document.cpp	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/Source/WebCore/dom/Document.cpp	2019-09-23 21:56:43 UTC (rev 250255)
@@ -5851,14 +5851,15 @@
         return;
     }
 
-    Document* openerDocument = openerFrame ? openerFrame->document() : nullptr;
+    contentSecurityPolicy()->copyStateFrom(ownerFrame->document()->contentSecurityPolicy());
+    contentSecurityPolicy()->updateSourceSelf(ownerFrame->document()->securityOrigin());
 
     // Per <http://www.w3.org/TR/upgrade-insecure-requests/>, new browsing contexts must inherit from an
     // ongoing set of upgraded requests. When opening a new browsing context, we need to capture its
     // existing upgrade request. Nested browsing contexts are handled during DocumentWriter::begin.
-    if (openerDocument)
+    if (auto* openerDocument = openerFrame ? openerFrame->document() : nullptr)
         contentSecurityPolicy()->inheritInsecureNavigationRequestsToUpgradeFromOpener(*openerDocument->contentSecurityPolicy());
-    
+
     if (isSandboxed(SandboxOrigin)) {
         // If we're supposed to inherit our security origin from our owner,
         // but we're also sandboxed, the only thing we inherit is the ability
@@ -5875,53 +5876,26 @@
     setSecurityOriginPolicy(ownerFrame->document()->securityOriginPolicy());
 }
 
-// FIXME: The current criterion is stricter than <https://www.w3.org/TR/CSP3/#security-inherit-csp> (Editor's Draft, 28 February 2019).
-bool Document::shouldInheritContentSecurityPolicy() const
+void Document::initContentSecurityPolicy()
 {
-    ASSERT(m_frame);
-    if (SecurityPolicy::shouldInheritSecurityOriginFromOwner(m_url))
-        return true;
-    if (m_url.protocolIsData() || m_url.protocolIsBlob())
-        return true;
-    if (!isPluginDocument())
-        return false;
-    if (m_frame->tree().parent())
-        return true;
-    Frame* openerFrame = m_frame->loader().opener();
-    if (!openerFrame)
-        return false;
-    return openerFrame->document()->securityOrigin().canAccess(securityOrigin());
-}
-
-void Document::initContentSecurityPolicy(ContentSecurityPolicy* previousPolicy)
-{
-    // 1. Inherit Upgrade Insecure Requests
-    Frame* parentFrame = m_frame->tree().parent();
+    auto* parentFrame = m_frame->tree().parent();
     if (parentFrame)
         contentSecurityPolicy()->copyUpgradeInsecureRequestStateFrom(*parentFrame->document()->contentSecurityPolicy());
 
-    // 2. Inherit Content Security Policy (without copying Upgrade Insecure Requests state).
-    if (!shouldInheritContentSecurityPolicy())
+    // FIXME: Remove this special plugin document logic. We are stricter than the CSP 3 spec. with regards to plugins: we prefer to
+    // inherit the full policy unless the plugin document is opened in a new window. The CSP 3 spec. implies that only plugin documents
+    // delivered with a local scheme (e.g. blob, file, data) should inherit a policy.
+    if (!isPluginDocument())
         return;
-    ContentSecurityPolicy* ownerPolicy = nullptr;
-    if (previousPolicy && (m_url.protocolIsData() || m_url.protocolIsBlob()))
-        ownerPolicy = previousPolicy;
-    if (!ownerPolicy) {
-        Frame* ownerFrame = parentFrame;
-        if (!ownerFrame)
-            ownerFrame = m_frame->loader().opener();
-        if (ownerFrame)
-            ownerPolicy = ownerFrame->document()->contentSecurityPolicy();
-    }
-    if (!ownerPolicy)
+    auto* openerFrame = m_frame->loader().opener();
+    bool shouldInhert = parentFrame || (openerFrame && openerFrame->document()->securityOrigin().canAccess(securityOrigin()));
+    if (!shouldInhert)
         return;
-    // FIXME: We are stricter than the CSP 3 spec. with regards to plugins: we prefer to inherit the full policy unless the plugin
-    // document is opened in a new window. The CSP 3 spec. implies that only plugin documents delivered with a local scheme (e.g. blob,
-    // file, data) should inherit a policy.
-    if (isPluginDocument() && m_frame->loader().opener())
-        contentSecurityPolicy()->createPolicyForPluginDocumentFrom(*ownerPolicy);
+    setContentSecurityPolicy(makeUnique<ContentSecurityPolicy>(URL { m_url }, *this));
+    if (openerFrame)
+        contentSecurityPolicy()->createPolicyForPluginDocumentFrom(*openerFrame->document()->contentSecurityPolicy());
     else
-        contentSecurityPolicy()->copyStateFrom(ownerPolicy);
+        contentSecurityPolicy()->copyStateFrom(parentFrame->document()->contentSecurityPolicy());
 }
 
 bool Document::isContextThread() const

Modified: trunk/Source/WebCore/dom/Document.h (250254 => 250255)


--- trunk/Source/WebCore/dom/Document.h	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/Source/WebCore/dom/Document.h	2019-09-23 21:56:43 UTC (rev 250255)
@@ -1144,7 +1144,7 @@
     HashSet<SVGUseElement*> const svgUseElements() const { return m_svgUseElements; }
 
     void initSecurityContext();
-    void initContentSecurityPolicy(ContentSecurityPolicy* previousPolicy);
+    void initContentSecurityPolicy();
 
     void updateURLForPushOrReplaceState(const URL&);
     void statePopped(Ref<SerializedScriptValue>&&);
@@ -1550,8 +1550,6 @@
     friend class IgnoreOpensDuringUnloadCountIncrementer;
     friend class IgnoreDestructiveWriteCountIncrementer;
 
-    bool shouldInheritContentSecurityPolicy() const;
-
     void updateTitleElement(Element& changingTitleElement);
     void willDetachPage() final;
     void frameDestroyed() final;

Modified: trunk/Source/WebCore/dom/SecurityContext.cpp (250254 => 250255)


--- trunk/Source/WebCore/dom/SecurityContext.cpp	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/Source/WebCore/dom/SecurityContext.cpp	2019-09-23 21:56:43 UTC (rev 250255)
@@ -53,7 +53,7 @@
     return &m_securityOriginPolicy->origin();
 }
 
-void SecurityContext::setContentSecurityPolicy(std::unique_ptr<ContentSecurityPolicy> contentSecurityPolicy)
+void SecurityContext::setContentSecurityPolicy(std::unique_ptr<ContentSecurityPolicy>&& contentSecurityPolicy)
 {
     m_contentSecurityPolicy = WTFMove(contentSecurityPolicy);
 }

Modified: trunk/Source/WebCore/dom/SecurityContext.h (250254 => 250255)


--- trunk/Source/WebCore/dom/SecurityContext.h	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/Source/WebCore/dom/SecurityContext.h	2019-09-23 21:56:43 UTC (rev 250255)
@@ -77,6 +77,11 @@
     //       that already contains content.
     void setSecurityOriginPolicy(RefPtr<SecurityOriginPolicy>&&);
 
+    // Explicitly override the content security policy for this security context.
+    // Note: It is dangerous to change the content security policy of a script
+    //       context that already contains content.
+    void setContentSecurityPolicy(std::unique_ptr<ContentSecurityPolicy>&&);
+
     WEBCORE_EXPORT SecurityOrigin* securityOrigin() const;
 
     static SandboxFlags parseSandboxPolicy(const String& policy, String& invalidTokensErrorMessage);
@@ -105,8 +110,6 @@
     SecurityContext();
     virtual ~SecurityContext();
 
-    void setContentSecurityPolicy(std::unique_ptr<ContentSecurityPolicy>);
-
     // It's only appropriate to call this during security context initialization; it's needed for
     // flags that can't be disabled with allow-* attributes, such as SandboxNavigation.
     void disableSandboxFlags(SandboxFlags mask) { m_sandboxFlags &= ~mask; }

Modified: trunk/Source/WebCore/loader/DocumentWriter.cpp (250254 => 250255)


--- trunk/Source/WebCore/loader/DocumentWriter.cpp	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/Source/WebCore/loader/DocumentWriter.cpp	2019-09-23 21:56:43 UTC (rev 250255)
@@ -140,9 +140,8 @@
 
     // Temporarily extend the lifetime of the existing document so that FrameLoader::clear() doesn't destroy it as
     // we need to retain its ongoing set of upgraded requests in new navigation contexts per <http://www.w3.org/TR/upgrade-insecure-requests/>
-    // and we may also need to inherit its Content Security Policy in FrameLoader::didBeginDocument().
+    // and we may also need to inherit its Content Security Policy below.
     RefPtr<Document> existingDocument = m_frame->document();
-    auto* previousContentSecurityPolicy = existingDocument ? existingDocument->contentSecurityPolicy() : nullptr;
 
     WTF::Function<void()> handleDOMWindowCreation = [this, document = document.copyRef(), url] {
         if (m_frame->loader().stateMachine().isDisplayingInitialEmptyDocument() && m_frame->document()->isSecureTransitionTo(url))
@@ -165,18 +164,31 @@
     m_frame->loader().setOutgoingReferrer(url);
     m_frame->setDocument(document.copyRef());
 
-    if (previousContentSecurityPolicy)
-        document->contentSecurityPolicy()->setInsecureNavigationRequestsToUpgrade(previousContentSecurityPolicy->takeNavigationRequestsToUpgrade());
-
     if (m_decoder)
         document->setDecoder(m_decoder.get());
     if (ownerDocument) {
+        // |document| is the result of evaluating a _javascript_ URL.
         document->setCookieURL(ownerDocument->cookieURL());
         document->setSecurityOriginPolicy(ownerDocument->securityOriginPolicy());
         document->setStrictMixedContentMode(ownerDocument->isStrictMixedContentMode());
+
+        document->setContentSecurityPolicy(makeUnique<ContentSecurityPolicy>(URL { url }, document));
+        document->contentSecurityPolicy()->copyStateFrom(ownerDocument->contentSecurityPolicy());
+        document->contentSecurityPolicy()->setInsecureNavigationRequestsToUpgrade(ownerDocument->contentSecurityPolicy()->takeNavigationRequestsToUpgrade());
+    } else if (existingDocument) {
+        if (url.protocolIsData() || url.protocolIsBlob()) {
+            document->setContentSecurityPolicy(makeUnique<ContentSecurityPolicy>(URL { url }, document));
+            document->contentSecurityPolicy()->copyStateFrom(existingDocument->contentSecurityPolicy());
+
+            // Fix up 'self' for blob: and data:, which is inherited from its embedding document or opener.
+            auto* parentFrame = m_frame->tree().parent();
+            if (auto* ownerFrame = parentFrame ? parentFrame : m_frame->loader().opener())
+                document->contentSecurityPolicy()->updateSourceSelf(ownerFrame->document()->securityOrigin());
+        }
+        document->contentSecurityPolicy()->setInsecureNavigationRequestsToUpgrade(existingDocument->contentSecurityPolicy()->takeNavigationRequestsToUpgrade());
     }
 
-    m_frame->loader().didBeginDocument(dispatch, previousContentSecurityPolicy);
+    m_frame->loader().didBeginDocument(dispatch);
 
     document->implicitOpen();
 

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (250254 => 250255)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2019-09-23 21:56:43 UTC (rev 250255)
@@ -719,7 +719,7 @@
     m_outgoingReferrer = url.strippedForUseAsReferrer();
 }
 
-void FrameLoader::didBeginDocument(bool dispatch, ContentSecurityPolicy* previousPolicy)
+void FrameLoader::didBeginDocument(bool dispatch)
 {
     m_needsClear = true;
     m_isComplete = false;
@@ -735,7 +735,7 @@
         dispatchDidClearWindowObjectsInAllWorlds();
 
     updateFirstPartyForCookies();
-    m_frame.document()->initContentSecurityPolicy(previousPolicy);
+    m_frame.document()->initContentSecurityPolicy();
 
     const Settings& settings = m_frame.settings();
     m_frame.document()->cachedResourceLoader().setImagesEnabled(settings.areImagesEnabled());

Modified: trunk/Source/WebCore/loader/FrameLoader.h (250254 => 250255)


--- trunk/Source/WebCore/loader/FrameLoader.h	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/Source/WebCore/loader/FrameLoader.h	2019-09-23 21:56:43 UTC (rev 250255)
@@ -231,7 +231,7 @@
     void didExplicitOpen();
 
     // Callbacks from DocumentWriter
-    void didBeginDocument(bool dispatchWindowObjectAvailable, ContentSecurityPolicy* previousPolicy);
+    void didBeginDocument(bool dispatchWindowObjectAvailable);
 
     void receivedFirstData();
 

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h (250254 => 250255)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h	2019-09-23 21:08:31 UTC (rev 250254)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h	2019-09-23 21:56:43 UTC (rev 250255)
@@ -172,10 +172,10 @@
     void setInsecureNavigationRequestsToUpgrade(HashSet<SecurityOriginData>&&);
 
     void setClient(ContentSecurityPolicyClient* client) { m_client = client; }
+    void updateSourceSelf(const SecurityOrigin&);
 
 private:
     void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), const WTF::OrdinalNumber& contextColumn = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const;
-    void updateSourceSelf(const SecurityOrigin&);
     void applyPolicyToScriptExecutionContext();
 
     // Implements the deprecated CSP2 "strip uri for reporting" algorithm from <https://www.w3.org/TR/CSP2/#violation-reports>.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to