Title: [204521] trunk
Revision
204521
Author
[email protected]
Date
2016-08-16 13:32:57 -0700 (Tue, 16 Aug 2016)

Log Message

Upgrade-Insecure-Request state is improperly retained between navigations
https://bugs.webkit.org/show_bug.cgi?id=160905
<rdar://problem/27075526>

Reviewed by Andy Estes.

Source/WebCore:

Correct the handling of Upgrade-Insecure-Request state to match the specification, so that
performing top-level navigation to sites that do not have the Upgrade-Insecure-Request header
does not automatically upgrade insecure loads. The same loads performed in an iframe should
be upgraded.

The iframe case was already handled in our tests, but a new test is added that models the top-level
navigation and confirms that an upgrade is not performed.

Tests: http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation.html

* dom/Document.cpp:
(WebCore::Document::initContentSecurityPolicy): Properly inherit Upgrade-Insecure-Request state for children
of existing frames.
* loader/DocumentWriter.cpp:
(WebCore::DocumentWriter::begin): Retain the history of upgraded resources (per the specification) so that
we continue to upgrade resources that were upgraded during earlier navigations. Note that we do NOT want to
retain the state of the Upgrade-Insecure-Requests header itself.
* page/csp/ContentSecurityPolicy.cpp:
(WebCore::ContentSecurityPolicy::copyStateFrom): Update to use new helper function.
(WebCore::ContentSecurityPolicy::copyUpgradeInsecureRequestStateFrom): New helper function.
* page/csp/ContentSecurityPolicy.h:

LayoutTests:

* http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation-expected.txt: Added.
* http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation.html: Added.
* http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/resources/insecure-site.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (204520 => 204521)


--- trunk/LayoutTests/ChangeLog	2016-08-16 19:57:00 UTC (rev 204520)
+++ trunk/LayoutTests/ChangeLog	2016-08-16 20:32:57 UTC (rev 204521)
@@ -1,3 +1,15 @@
+2016-08-16  Brent Fulgham  <[email protected]>
+
+        Upgrade-Insecure-Request state is improperly retained between navigations
+        https://bugs.webkit.org/show_bug.cgi?id=160905
+        <rdar://problem/27075526>
+
+        Reviewed by Andy Estes.
+
+        * http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation-expected.txt: Added.
+        * http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation.html: Added.
+        * http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/resources/insecure-site.html: Added.
+
 2016-08-16  Chris Dumez  <[email protected]>
 
         ctx.drawImage should clip source rect if it is outside the source image

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation-expected.txt (0 => 204521)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation-expected.txt	2016-08-16 20:32:57 UTC (rev 204521)
@@ -0,0 +1,14 @@
+ALERT: PASS
+ALERT: PASS
+This page should be loaded insecurely as a navigation from the secure site 'secure-second-site.html'. The secure domain should have set the Upgrade-Insecure-Requests header, but this new navigation should have cleared this state.
+
+The following script is loaded using 'http', and should NOT be upgraded to 'https'.
+
+If this test passes there should be two PASS messages in the output.
+
+
+
+============== Back Forward List ==============
+        http://127.0.0.1:8000/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation.html  **nav target**
+curr->  http://127.0.0.1:8000/security/contentSecurityPolicy/upgrade-insecure-requests/resources/insecure-site.html  **nav target**
+===============================================

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation.html (0 => 204521)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation.html	2016-08-16 20:32:57 UTC (rev 204521)
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
+</head>
+<body>
+    <script>
+    if (window.testRunner)
+        testRunner.dumpAsText();
+    </script>
+    <div>
+        <p>The following script is loaded using 'http', but it should be upgraded to 'https' due to the
+'upgrade-insecure-requests' header.</p>
+        <script src=""
+    <div>
+    <script>
+    if (window.testRunner)
+        testRunner.queueLoad("http://127.0.0.1:8000/security/contentSecurityPolicy/upgrade-insecure-requests/resources/insecure-site.html");
+    </script>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/resources/insecure-site.html (0 => 204521)


--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/resources/insecure-site.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/resources/insecure-site.html	2016-08-16 20:32:57 UTC (rev 204521)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<body>
+    <p>This page should be loaded insecurely as a navigation from the secure site 'secure-second-site.html'. The secure domain should have set the Upgrade-Insecure-Requests header,
+       but this new navigation should have cleared this state.</p>
+    <div>
+        <p>The following script is loaded using 'http', and should NOT be upgraded to 'https'.</p>
+        <script src=""
+        <p>If this test passes there should be two PASS messages in the output.</p>
+    <div>
+    <script>
+    if (window.testRunner)
+       testRunner.dumpBackForwardList();
+    </script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (204520 => 204521)


--- trunk/Source/WebCore/ChangeLog	2016-08-16 19:57:00 UTC (rev 204520)
+++ trunk/Source/WebCore/ChangeLog	2016-08-16 20:32:57 UTC (rev 204521)
@@ -1,3 +1,33 @@
+2016-08-16  Brent Fulgham  <[email protected]>
+
+        Upgrade-Insecure-Request state is improperly retained between navigations
+        https://bugs.webkit.org/show_bug.cgi?id=160905
+        <rdar://problem/27075526>
+
+        Reviewed by Andy Estes.
+
+        Correct the handling of Upgrade-Insecure-Request state to match the specification, so that
+        performing top-level navigation to sites that do not have the Upgrade-Insecure-Request header
+        does not automatically upgrade insecure loads. The same loads performed in an iframe should
+        be upgraded.
+
+        The iframe case was already handled in our tests, but a new test is added that models the top-level
+        navigation and confirms that an upgrade is not performed.
+
+        Tests: http/tests/security/contentSecurityPolicy/upgrade-insecure-requests/proper-uir-on-navigation.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::initContentSecurityPolicy): Properly inherit Upgrade-Insecure-Request state for children
+        of existing frames.
+        * loader/DocumentWriter.cpp:
+        (WebCore::DocumentWriter::begin): Retain the history of upgraded resources (per the specification) so that
+        we continue to upgrade resources that were upgraded during earlier navigations. Note that we do NOT want to
+        retain the state of the Upgrade-Insecure-Requests header itself.
+        * page/csp/ContentSecurityPolicy.cpp:
+        (WebCore::ContentSecurityPolicy::copyStateFrom): Update to use new helper function.
+        (WebCore::ContentSecurityPolicy::copyUpgradeInsecureRequestStateFrom): New helper function.
+        * page/csp/ContentSecurityPolicy.h:
+
 2016-08-16  Chris Dumez  <[email protected]>
 
         ctx.drawImage should clip source rect if it is outside the source image

Modified: trunk/Source/WebCore/dom/Document.cpp (204520 => 204521)


--- trunk/Source/WebCore/dom/Document.cpp	2016-08-16 19:57:00 UTC (rev 204520)
+++ trunk/Source/WebCore/dom/Document.cpp	2016-08-16 20:32:57 UTC (rev 204521)
@@ -5389,9 +5389,18 @@
 
 void Document::initContentSecurityPolicy()
 {
-    if (!m_frame->tree().parent() || (!shouldInheritSecurityOriginFromOwner(m_url) && !isPluginDocument()))
+    if (!m_frame->tree().parent())
         return;
 
+    if (!shouldInheritSecurityOriginFromOwner(m_url) && !isPluginDocument()) {
+        // Per <http://www.w3.org/TR/upgrade-insecure-requests/>, we need to retain an ongoing set of upgraded
+        // requests in new navigation contexts. Although this information is present when we construct the
+        // Document object, it is discard in the subsequent 'clear' statements below. So, we must capture it
+        ASSERT(m_frame->tree().parent()->document());
+        contentSecurityPolicy()->copyUpgradeInsecureRequestStateFrom(*m_frame->tree().parent()->document()->contentSecurityPolicy());
+        return;
+    }
+    
     contentSecurityPolicy()->copyStateFrom(m_frame->tree().parent()->document()->contentSecurityPolicy());
 }
 

Modified: trunk/Source/WebCore/loader/DocumentWriter.cpp (204520 => 204521)


--- trunk/Source/WebCore/loader/DocumentWriter.cpp	2016-08-16 19:57:00 UTC (rev 204520)
+++ trunk/Source/WebCore/loader/DocumentWriter.cpp	2016-08-16 20:32:57 UTC (rev 204521)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010. Adam Barth. All rights reserved.
+ * 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
@@ -149,11 +150,8 @@
     // Document object, it is discard in the subsequent 'clear' statements below. So, we must capture it
     // so we can restore it.
     HashSet<RefPtr<SecurityOrigin>> insecureNavigationRequestsToUpgrade;
-    bool upgradeInsecureRequests = false;
-    if (auto* existingDocument = m_frame->document()) {
-        upgradeInsecureRequests = existingDocument->contentSecurityPolicy()->upgradeInsecureRequests();
+    if (auto* existingDocument = m_frame->document())
         insecureNavigationRequestsToUpgrade = existingDocument->contentSecurityPolicy()->takeNavigationRequestsToUpgrade();
-    }
     
     m_frame->loader().clear(document.ptr(), !shouldReuseDefaultView, !shouldReuseDefaultView);
     clear();
@@ -169,7 +167,6 @@
     m_frame->loader().setOutgoingReferrer(url);
     m_frame->setDocument(document.copyRef());
 
-    document->contentSecurityPolicy()->setUpgradeInsecureRequests(upgradeInsecureRequests);
     document->contentSecurityPolicy()->setInsecureNavigationRequestsToUpgrade(WTFMove(insecureNavigationRequestsToUpgrade));
 
     if (m_decoder)

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp (204520 => 204521)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp	2016-08-16 19:57:00 UTC (rev 204520)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp	2016-08-16 20:32:57 UTC (rev 204521)
@@ -114,10 +114,15 @@
     for (auto& policy : other->m_policies)
         didReceiveHeader(policy->header(), policy->headerType(), ContentSecurityPolicy::PolicyFrom::Inherited);
 
-    m_upgradeInsecureRequests = other->m_upgradeInsecureRequests;
-    m_insecureNavigationRequestsToUpgrade.add(other->m_insecureNavigationRequestsToUpgrade.begin(), other->m_insecureNavigationRequestsToUpgrade.end());
+    copyUpgradeInsecureRequestStateFrom(*other);
 }
 
+void ContentSecurityPolicy::copyUpgradeInsecureRequestStateFrom(const ContentSecurityPolicy& other)
+{
+    m_upgradeInsecureRequests = other.m_upgradeInsecureRequests;
+    m_insecureNavigationRequestsToUpgrade.add(other.m_insecureNavigationRequestsToUpgrade.begin(), other.m_insecureNavigationRequestsToUpgrade.end());
+}
+
 void ContentSecurityPolicy::didCreateWindowShell(JSDOMWindowShell& windowShell) const
 {
     JSDOMWindow* window = windowShell.window();

Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h (204520 => 204521)


--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h	2016-08-16 19:57:00 UTC (rev 204520)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h	2016-08-16 20:32:57 UTC (rev 204521)
@@ -69,6 +69,7 @@
     ~ContentSecurityPolicy();
 
     void copyStateFrom(const ContentSecurityPolicy*);
+    void copyUpgradeInsecureRequestStateFrom(const ContentSecurityPolicy&);
 
     void didCreateWindowShell(JSDOMWindowShell&) const;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to