OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <vector> |
| 6 |
| 7 #include "content/common/feature_policy/feature_policy.h" |
| 8 #include "content/public/browser/render_frame_host.h" |
| 9 #include "content/public/browser/web_contents.h" |
| 10 #include "content/public/test/navigation_simulator.h" |
| 11 #include "content/public/test/test_renderer_host.h" |
| 12 #include "content/test/test_render_frame_host.h" |
| 13 #include "third_party/WebKit/public/platform/WebFeaturePolicyFeature.h" |
| 14 #include "third_party/WebKit/public/web/WebSandboxFlags.h" |
| 15 #include "url/gurl.h" |
| 16 #include "url/origin.h" |
| 17 |
| 18 namespace content { |
| 19 |
| 20 // Integration tests for feature policy setup and querying through a RFH. These |
| 21 // tests are not meant to cover every edge case as the FeaturePolicy class |
| 22 // itself is tested thoroughly in feature_policy_unittest.cc. Instead they are |
| 23 // meant to ensure that integration with RenderFrameHost works correctly. |
| 24 class RenderFrameHostFeaturePolicyTest |
| 25 : public content::RenderViewHostTestHarness { |
| 26 protected: |
| 27 static constexpr const char* kOrigin1 = "https://google.com"; |
| 28 static constexpr const char* kOrigin2 = "https://maps.google.com"; |
| 29 static constexpr const char* kOrigin3 = "https://example.com"; |
| 30 static constexpr const char* kOrigin4 = "https://test.com"; |
| 31 |
| 32 static const blink::WebFeaturePolicyFeature kDefaultEnabledFeature = |
| 33 blink::WebFeaturePolicyFeature::kDocumentWrite; |
| 34 static const blink::WebFeaturePolicyFeature kDefaultSelfFeature = |
| 35 blink::WebFeaturePolicyFeature::kGeolocation; |
| 36 |
| 37 RenderFrameHost* GetMainRFH(const char* origin) { |
| 38 RenderFrameHost* result = web_contents()->GetMainFrame(); |
| 39 RenderFrameHostTester::For(result)->InitializeRenderFrameIfNeeded(); |
| 40 SimulateNavigation(&result, GURL(origin)); |
| 41 return result; |
| 42 } |
| 43 |
| 44 RenderFrameHost* AddChildRFH(RenderFrameHost* parent, const char* origin) { |
| 45 RenderFrameHost* result = |
| 46 RenderFrameHostTester::For(parent)->AppendChild(""); |
| 47 RenderFrameHostTester::For(result)->InitializeRenderFrameIfNeeded(); |
| 48 SimulateNavigation(&result, GURL(origin)); |
| 49 return result; |
| 50 } |
| 51 |
| 52 // The header policy should only be set once on page load, so we refresh the |
| 53 // page to simulate that. |
| 54 void RefreshPageAndSetHeaderPolicy(RenderFrameHost** rfh, |
| 55 blink::WebFeaturePolicyFeature feature, |
| 56 const std::vector<std::string>& origins) { |
| 57 RenderFrameHost* current = *rfh; |
| 58 SimulateNavigation(¤t, current->GetLastCommittedURL()); |
| 59 static_cast<TestRenderFrameHost*>(current)->OnDidSetFeaturePolicyHeader( |
| 60 CreateFPHeader(feature, origins)); |
| 61 *rfh = current; |
| 62 } |
| 63 |
| 64 void SetContainerPolicy(RenderFrameHost* parent, |
| 65 RenderFrameHost* child, |
| 66 blink::WebFeaturePolicyFeature feature, |
| 67 const std::vector<std::string>& origins) { |
| 68 static_cast<TestRenderFrameHost*>(parent)->OnDidChangeFramePolicy( |
| 69 child->GetRoutingID(), blink::WebSandboxFlags(), |
| 70 CreateFPHeader(feature, origins)); |
| 71 } |
| 72 |
| 73 void SimulateNavigation(RenderFrameHost** rfh, const GURL& url) { |
| 74 auto navigation_simulator = |
| 75 NavigationSimulator::CreateRendererInitiated(url, *rfh); |
| 76 navigation_simulator->Commit(); |
| 77 *rfh = navigation_simulator->GetFinalRenderFrameHost(); |
| 78 } |
| 79 |
| 80 private: |
| 81 ParsedFeaturePolicyHeader CreateFPHeader( |
| 82 blink::WebFeaturePolicyFeature feature, |
| 83 const std::vector<std::string>& origins) { |
| 84 ParsedFeaturePolicyHeader result(1); |
| 85 result[0].feature = feature; |
| 86 result[0].matches_all_origins = false; |
| 87 for (const std::string& origin : origins) |
| 88 result[0].origins.push_back(url::Origin(GURL(origin))); |
| 89 return result; |
| 90 } |
| 91 }; |
| 92 |
| 93 TEST_F(RenderFrameHostFeaturePolicyTest, DefaultPolicy) { |
| 94 RenderFrameHost* parent = GetMainRFH(kOrigin1); |
| 95 RenderFrameHost* child = AddChildRFH(parent, kOrigin2); |
| 96 |
| 97 EXPECT_TRUE(parent->IsFeatureEnabled(kDefaultEnabledFeature)); |
| 98 EXPECT_TRUE(parent->IsFeatureEnabled(kDefaultSelfFeature)); |
| 99 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultEnabledFeature)); |
| 100 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 101 } |
| 102 |
| 103 TEST_F(RenderFrameHostFeaturePolicyTest, HeaderPolicy) { |
| 104 RenderFrameHost* parent = GetMainRFH(kOrigin1); |
| 105 |
| 106 // Enable the feature for the child in the parent frame. |
| 107 RefreshPageAndSetHeaderPolicy(&parent, kDefaultSelfFeature, |
| 108 {kOrigin1, kOrigin2}); |
| 109 |
| 110 // Create the child. |
| 111 RenderFrameHost* child = AddChildRFH(parent, kOrigin2); |
| 112 |
| 113 EXPECT_TRUE(parent->IsFeatureEnabled(kDefaultSelfFeature)); |
| 114 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 115 |
| 116 // Set an empty whitelist in the child to test that the policies combine |
| 117 // correctly. |
| 118 RefreshPageAndSetHeaderPolicy(&child, kDefaultSelfFeature, |
| 119 std::vector<std::string>()); |
| 120 |
| 121 EXPECT_TRUE(parent->IsFeatureEnabled(kDefaultSelfFeature)); |
| 122 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 123 |
| 124 // Re-enable the feature in the child. |
| 125 RefreshPageAndSetHeaderPolicy(&child, kDefaultSelfFeature, {kOrigin2}); |
| 126 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 127 |
| 128 // Navigate the child. Check that the feature is disabled. |
| 129 SimulateNavigation(&child, GURL(kOrigin3)); |
| 130 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 131 } |
| 132 |
| 133 TEST_F(RenderFrameHostFeaturePolicyTest, ContainerPolicy) { |
| 134 RenderFrameHost* parent = GetMainRFH(kOrigin1); |
| 135 RenderFrameHost* child = AddChildRFH(parent, kOrigin2); |
| 136 |
| 137 // Set a container policy on origin 3 to give it the feature. It should not |
| 138 // be enabled because container policy will only take effect after navigation. |
| 139 SetContainerPolicy(parent, child, kDefaultSelfFeature, {kOrigin2, kOrigin3}); |
| 140 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 141 |
| 142 // Navigate the child so that the container policy takes effect. |
| 143 SimulateNavigation(&child, GURL(kOrigin3)); |
| 144 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 145 |
| 146 // // Navigate the child again, the feature should not be enabled. |
| 147 // SimulateNavigation(&child, GURL(kOrigin4)); |
| 148 // EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 149 } |
| 150 |
| 151 TEST_F(RenderFrameHostFeaturePolicyTest, HeaderAndContainerPolicy) { |
| 152 RenderFrameHost* parent = GetMainRFH(kOrigin1); |
| 153 |
| 154 // Set a header policy and container policy. Check that they both take effect. |
| 155 RefreshPageAndSetHeaderPolicy(&parent, kDefaultSelfFeature, |
| 156 {kOrigin1, kOrigin2}); |
| 157 |
| 158 RenderFrameHost* child = AddChildRFH(parent, kOrigin2); |
| 159 SetContainerPolicy(parent, child, kDefaultSelfFeature, {kOrigin3}); |
| 160 |
| 161 // The feature should be enabled in kOrigin2, kOrigin3 but not kOrigin4. |
| 162 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 163 SimulateNavigation(&child, GURL(kOrigin3)); |
| 164 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 165 SimulateNavigation(&child, GURL(kOrigin4)); |
| 166 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 167 |
| 168 // Change the header policy to turn off the feature. It should be disabled in |
| 169 // all children. |
| 170 RefreshPageAndSetHeaderPolicy(&parent, kDefaultSelfFeature, |
| 171 std::vector<std::string>()); |
| 172 child = AddChildRFH(parent, kOrigin2); |
| 173 SetContainerPolicy(parent, child, kDefaultSelfFeature, {kOrigin3}); |
| 174 |
| 175 SimulateNavigation(&child, GURL(kOrigin2)); |
| 176 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 177 SimulateNavigation(&child, GURL(kOrigin3)); |
| 178 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); |
| 179 } |
| 180 |
| 181 } // namespace content |
OLD | NEW |