Title: [217054] trunk
Revision
217054
Author
[email protected]
Date
2017-05-18 11:55:45 -0700 (Thu, 18 May 2017)

Log Message

REGRESSION (r209608): Cross-origin plugin document opened in child window blocked by parent
window CSP when object-src 'none' is set
https://bugs.webkit.org/show_bug.cgi?id=172038
<rdar://problem/32258262>

Reviewed by Andy Estes.

Source/WebCore:

Fixes an issue where a cross-origin plugin document opened in a child window would inherit
the Content Security Policy (CSP) of its opener. In particular, a cross-origin plugin
document opened in a child window would be blocked when the CSP of its opener disallows
plugins (e.g. object-source 'none').

Prior to r209608 a document opened in a child window never inherited the CSP from its opener
and a plugin document loaded in a subframe would unconditionally inherit the CSP from its
parent frame. So, a plugin document opened in a child window would be allowed to load
regardless of whether its opener had a CSP that prevented plugins. Following r209608 a
document opened in a child window would inherit its CSP from its opener if and only if it
would inherit the security origin from its opener (e.g. about:blank) or was a plugin
document. The latter condition makes plugin documents opened in a child window unconditionally
inherit the CSP from their opener and is the cause of this bug. It seems reasonable to exempt
cross-origin plugin documents opened in a child window from the CSP inheritance rule because
such documents cannot compromise the origin of their opener. Same-origin plugin documents
opened in a child window will continue to inherit the CSP from their opener because such
documents can compromise the origin of their opener.

Tests: http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window.html
       http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window.html
       http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window.html

* dom/Document.cpp:
(WebCore::Document::shouldInheritContentSecurityPolicyFromOwner): Added.
(WebCore::Document::initContentSecurityPolicy):
* dom/Document.h:

Tools:

Teach the test Netscape plugin to look for a URL that contains plugin-document-alert-and-notify-done.pl.
When it sees this URL it will show a _javascript_ alert and call testRunner.notifyDone().

* DumpRenderTree/TestNetscapePlugIn/main.cpp:
(NPP_New):

LayoutTests:

Adds tests to ensure that a same-origin- and cross-origin- plugin document opened in a child
window inherit and do not inherit the CSP of its opener, respectively. Also adds a test to
ensure that an about:blank window inherits the CSP plugin policy of its opener.

* http/tests/plugins/resources/plugin-document-alert-and-notify-done.pl: Added.
* http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window.html: Added.
* http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window.html: Added.
* http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window.html: Added.
* platform/ios/TestExpectations: Skip added tests as iOS does not support plugins.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (217053 => 217054)


--- trunk/LayoutTests/ChangeLog	2017-05-18 18:26:29 UTC (rev 217053)
+++ trunk/LayoutTests/ChangeLog	2017-05-18 18:55:45 UTC (rev 217054)
@@ -1,3 +1,25 @@
+2017-05-18  Daniel Bates  <[email protected]>
+
+        REGRESSION (r209608): Cross-origin plugin document opened in child window blocked by parent
+        window CSP when object-src 'none' is set
+        https://bugs.webkit.org/show_bug.cgi?id=172038
+        <rdar://problem/32258262>
+
+        Reviewed by Andy Estes.
+
+        Adds tests to ensure that a same-origin- and cross-origin- plugin document opened in a child
+        window inherit and do not inherit the CSP of its opener, respectively. Also adds a test to
+        ensure that an about:blank window inherits the CSP plugin policy of its opener.
+
+        * http/tests/plugins/resources/plugin-document-alert-and-notify-done.pl: Added.
+        * http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window.html: Added.
+        * http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window.html: Added.
+        * http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window.html: Added.
+        * platform/ios/TestExpectations: Skip added tests as iOS does not support plugins.
+
 2017-05-18  Keith Miller  <[email protected]>
 
         WebAssembly API: test with neutered inputs

Added: trunk/LayoutTests/http/tests/plugins/resources/plugin-document-alert-and-notify-done.pl (0 => 217054)


--- trunk/LayoutTests/http/tests/plugins/resources/plugin-document-alert-and-notify-done.pl	                        (rev 0)
+++ trunk/LayoutTests/http/tests/plugins/resources/plugin-document-alert-and-notify-done.pl	2017-05-18 18:55:45 UTC (rev 217054)
@@ -0,0 +1,7 @@
+#!/usr/bin/perl -wT
+use strict;
+
+# Do not rename this file. The TestNetscapePlugin is hardcoded to look for this filename
+# to trigger a _javascript_ alert and call testRunner.notifyDone().
+print "Content-Type: application/x-webkit-test-netscape\n\n";
+print "This is a mock plugin. It alerts when loaded and calls testRunner.notifyDone()";
Property changes on: trunk/LayoutTests/http/tests/plugins/resources/plugin-document-alert-and-notify-done.pl
___________________________________________________________________

Added: svn:executable

+* \ No newline at end of property

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window-expected.txt (0 => 217054)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window-expected.txt	2017-05-18 18:55:45 UTC (rev 217054)
@@ -0,0 +1,2 @@
+ALERT: Plugin Loaded!
+

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window.html (0 => 217054)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window.html	2017-05-18 18:55:45 UTC (rev 217054)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; object-src 'none'">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.setCanOpenWindows();
+    testRunner.setCloseRemainingWindowsWhenComplete(true);
+    testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<script>
+window.open("http://localhost:8000/plugins/resources/plugin-document-alert-and-notify-done.pl");
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window-expected.txt (0 => 217054)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window-expected.txt	2017-05-18 18:55:45 UTC (rev 217054)
@@ -0,0 +1,2 @@
+CONSOLE MESSAGE: Refused to load data:application/x-webkit-test-netscape,alertwhenloaded because it does not appear in the object-src directive of the Content Security Policy.
+

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window.html (0 => 217054)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window.html	2017-05-18 18:55:45 UTC (rev 217054)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; object-src 'none'">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.setCanOpenWindows();
+    testRunner.setCloseRemainingWindowsWhenComplete(true);
+    testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<pre id="console"></pre>
+<script>
+var childWindow = window.open("about:blank");
+var markup = [
+    '<object data=""
+    '<script>',
+    'function done()',
+    '{',
+    '    if (window.testRunner)',
+    '        testRunner.notifyDone();',
+    '}',
+    'window.setTimeout(done, 500);',
+    '<' + '/script>',
+]
+childWindow.document.write(markup.join("\n"));
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window-expected.txt (0 => 217054)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window-expected.txt	2017-05-18 18:55:45 UTC (rev 217054)
@@ -0,0 +1,2 @@
+CONSOLE MESSAGE: Refused to load http://127.0.0.1:8000/plugins/resources/plugin-document-alert-and-notify-done.pl because it does not appear in the object-src directive of the Content Security Policy.
+

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window.html (0 => 217054)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window.html	2017-05-18 18:55:45 UTC (rev 217054)
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'; object-src 'none'">
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.setCanOpenWindows();
+    testRunner.setCloseRemainingWindowsWhenComplete(true);
+    testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<script>
+checkDidLoadAndNotifyDone(window.open("http://127.0.0.1:8000/plugins/resources/plugin-document-alert-and-notify-done.pl"));
+
+// Assumes that the specified window is loading a same-origin document.
+function checkDidLoadAndNotifyDone(childWindow)
+{
+    function checkDidLoad() {
+        if (childWindow.document.location.origin !== document.location.origin)
+            return;
+        // Child window did load
+        window.clearInterval(intervalID);
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }
+    intervalID = window.setInterval(checkDidLoad, 10);
+}
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/ios/TestExpectations (217053 => 217054)


--- trunk/LayoutTests/platform/ios/TestExpectations	2017-05-18 18:26:29 UTC (rev 217053)
+++ trunk/LayoutTests/platform/ios/TestExpectations	2017-05-18 18:55:45 UTC (rev 217054)
@@ -126,6 +126,9 @@
 http/tests/security/contentSecurityPolicy/object-with-no-url-allowed-by-star.html
 http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-plugin-in-iframe.html
 http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-plugin-in-main-frame.html
+http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window.html
+http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window.html
+http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window.html
 
 # Pointer-lock not supported on iOS
 pointer-lock

Modified: trunk/Source/WebCore/ChangeLog (217053 => 217054)


--- trunk/Source/WebCore/ChangeLog	2017-05-18 18:26:29 UTC (rev 217053)
+++ trunk/Source/WebCore/ChangeLog	2017-05-18 18:55:45 UTC (rev 217054)
@@ -1,3 +1,39 @@
+2017-05-18  Daniel Bates  <[email protected]>
+
+        REGRESSION (r209608): Cross-origin plugin document opened in child window blocked by parent
+        window CSP when object-src 'none' is set
+        https://bugs.webkit.org/show_bug.cgi?id=172038
+        <rdar://problem/32258262>
+
+        Reviewed by Andy Estes.
+
+        Fixes an issue where a cross-origin plugin document opened in a child window would inherit
+        the Content Security Policy (CSP) of its opener. In particular, a cross-origin plugin
+        document opened in a child window would be blocked when the CSP of its opener disallows
+        plugins (e.g. object-source 'none').
+
+        Prior to r209608 a document opened in a child window never inherited the CSP from its opener
+        and a plugin document loaded in a subframe would unconditionally inherit the CSP from its
+        parent frame. So, a plugin document opened in a child window would be allowed to load
+        regardless of whether its opener had a CSP that prevented plugins. Following r209608 a
+        document opened in a child window would inherit its CSP from its opener if and only if it
+        would inherit the security origin from its opener (e.g. about:blank) or was a plugin
+        document. The latter condition makes plugin documents opened in a child window unconditionally
+        inherit the CSP from their opener and is the cause of this bug. It seems reasonable to exempt
+        cross-origin plugin documents opened in a child window from the CSP inheritance rule because
+        such documents cannot compromise the origin of their opener. Same-origin plugin documents
+        opened in a child window will continue to inherit the CSP from their opener because such
+        documents can compromise the origin of their opener.
+
+        Tests: http/tests/security/contentSecurityPolicy/cross-origin-plugin-document-allowed-in-child-window.html
+               http/tests/security/contentSecurityPolicy/plugin-blocked-in-about-blank-window.html
+               http/tests/security/contentSecurityPolicy/same-origin-plugin-document-blocked-in-child-window.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::shouldInheritContentSecurityPolicyFromOwner): Added.
+        (WebCore::Document::initContentSecurityPolicy):
+        * dom/Document.h:
+
 2017-05-18  Keith Miller  <[email protected]>
 
         WebAssembly API: test with neutered inputs

Modified: trunk/Source/WebCore/dom/Document.cpp (217053 => 217054)


--- trunk/Source/WebCore/dom/Document.cpp	2017-05-18 18:26:29 UTC (rev 217053)
+++ trunk/Source/WebCore/dom/Document.cpp	2017-05-18 18:55:45 UTC (rev 217054)
@@ -5213,15 +5213,31 @@
     setSecurityOriginPolicy(ownerFrame->document()->securityOriginPolicy());
 }
 
+bool Document::shouldInheritContentSecurityPolicyFromOwner() const
+{
+    ASSERT(m_frame);
+    if (shouldInheritSecurityOriginFromOwner(m_url))
+        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()
 {
+    // 1. Inherit Upgrade Insecure Requests
     Frame* parentFrame = m_frame->tree().parent();
     if (parentFrame)
         contentSecurityPolicy()->copyUpgradeInsecureRequestStateFrom(*parentFrame->document()->contentSecurityPolicy());
 
-    if (!shouldInheritSecurityOriginFromOwner(m_url) && !isPluginDocument())
+    // 2. Inherit Content Security Policy
+    if (!shouldInheritContentSecurityPolicyFromOwner())
         return;
-
     Frame* ownerFrame = parentFrame;
     if (!ownerFrame)
         ownerFrame = m_frame->loader().opener();

Modified: trunk/Source/WebCore/dom/Document.h (217053 => 217054)


--- trunk/Source/WebCore/dom/Document.h	2017-05-18 18:26:29 UTC (rev 217053)
+++ trunk/Source/WebCore/dom/Document.h	2017-05-18 18:55:45 UTC (rev 217054)
@@ -1326,6 +1326,8 @@
     friend class IgnoreDestructiveWriteCountIncrementer;
     friend class IgnoreOpensDuringUnloadCountIncrementer;
 
+    bool shouldInheritContentSecurityPolicyFromOwner() const;
+
     void detachFromFrame() { observeFrame(nullptr); }
 
     void updateTitleElement(Element* newTitleElement);

Modified: trunk/Tools/ChangeLog (217053 => 217054)


--- trunk/Tools/ChangeLog	2017-05-18 18:26:29 UTC (rev 217053)
+++ trunk/Tools/ChangeLog	2017-05-18 18:55:45 UTC (rev 217054)
@@ -1,3 +1,18 @@
+2017-05-18  Daniel Bates  <[email protected]>
+
+        REGRESSION (r209608): Cross-origin plugin document opened in child window blocked by parent
+        window CSP when object-src 'none' is set
+        https://bugs.webkit.org/show_bug.cgi?id=172038
+        <rdar://problem/32258262>
+
+        Reviewed by Andy Estes.
+
+        Teach the test Netscape plugin to look for a URL that contains plugin-document-alert-and-notify-done.pl.
+        When it sees this URL it will show a _javascript_ alert and call testRunner.notifyDone().
+
+        * DumpRenderTree/TestNetscapePlugIn/main.cpp:
+        (NPP_New):
+
 2017-05-18  Per Arne Vollan  <[email protected]>
 
         [Win] Many layout tests are failing.

Modified: trunk/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp (217053 => 217054)


--- trunk/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp	2017-05-18 18:26:29 UTC (rev 217053)
+++ trunk/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp	2017-05-18 18:55:45 UTC (rev 217054)
@@ -264,6 +264,8 @@
 #endif
         } else if (!strcasecmp(argn[i], "src") && strstr(argv[i], "plugin-document-has-focus.pl"))
             obj->testKeyboardFocusForPlugins = TRUE;
+        else if (!strcasecmp(argn[i], "src") && strstr(argv[i], "plugin-document-alert-and-notify-done.pl"))
+            executeScript(obj, "alert('Plugin Loaded!'); testRunner.notifyDone();");
         else if (!strcasecmp(argn[i], "evaluatescript")) {
             char* script = argv[i];
             if (script == strstr(script, "mouse::")) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to