Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/frame_host/render_frame_host_manager.h" | 5 #include "content/browser/frame_host/render_frame_host_manager.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <tuple> | 9 #include <tuple> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 17 #include "base/test/histogram_tester.h" | 17 #include "base/test/histogram_tester.h" |
| 18 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 19 #include "build/build_config.h" | 19 #include "build/build_config.h" |
| 20 #include "content/browser/frame_host/navigation_controller_impl.h" | 20 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 21 #include "content/browser/frame_host/navigation_entry_impl.h" | 21 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 22 #include "content/browser/frame_host/navigation_request.h" | 22 #include "content/browser/frame_host/navigation_request.h" |
| 23 #include "content/browser/frame_host/navigator.h" | 23 #include "content/browser/frame_host/navigator.h" |
| 24 #include "content/browser/frame_host/render_frame_proxy_host.h" | 24 #include "content/browser/frame_host/render_frame_proxy_host.h" |
| 25 #include "content/browser/site_instance_impl.h" | 25 #include "content/browser/site_instance_impl.h" |
| 26 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 26 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
| 27 #include "content/common/feature_policy/feature_policy.h" | |
| 27 #include "content/common/frame_messages.h" | 28 #include "content/common/frame_messages.h" |
| 28 #include "content/common/frame_owner_properties.h" | 29 #include "content/common/frame_owner_properties.h" |
| 29 #include "content/common/input_messages.h" | 30 #include "content/common/input_messages.h" |
| 30 #include "content/common/site_isolation_policy.h" | 31 #include "content/common/site_isolation_policy.h" |
| 31 #include "content/common/view_messages.h" | 32 #include "content/common/view_messages.h" |
| 32 #include "content/public/browser/notification_details.h" | 33 #include "content/public/browser/notification_details.h" |
| 33 #include "content/public/browser/notification_service.h" | 34 #include "content/public/browser/notification_service.h" |
| 34 #include "content/public/browser/notification_source.h" | 35 #include "content/public/browser/notification_source.h" |
| 35 #include "content/public/browser/notification_types.h" | 36 #include "content/public/browser/notification_types.h" |
| 36 #include "content/public/browser/render_process_host.h" | 37 #include "content/public/browser/render_process_host.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 48 #include "content/public/test/mock_render_process_host.h" | 49 #include "content/public/test/mock_render_process_host.h" |
| 49 #include "content/public/test/test_notification_tracker.h" | 50 #include "content/public/test/test_notification_tracker.h" |
| 50 #include "content/public/test/test_utils.h" | 51 #include "content/public/test/test_utils.h" |
| 51 #include "content/test/test_content_browser_client.h" | 52 #include "content/test/test_content_browser_client.h" |
| 52 #include "content/test/test_content_client.h" | 53 #include "content/test/test_content_client.h" |
| 53 #include "content/test/test_render_frame_host.h" | 54 #include "content/test/test_render_frame_host.h" |
| 54 #include "content/test/test_render_view_host.h" | 55 #include "content/test/test_render_view_host.h" |
| 55 #include "content/test/test_web_contents.h" | 56 #include "content/test/test_web_contents.h" |
| 56 #include "net/base/load_flags.h" | 57 #include "net/base/load_flags.h" |
| 57 #include "testing/gtest/include/gtest/gtest.h" | 58 #include "testing/gtest/include/gtest/gtest.h" |
| 59 #include "third_party/WebKit/public/platform/WebFeaturePolicyFeature.h" | |
| 58 #include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h" | 60 #include "third_party/WebKit/public/platform/WebInsecureRequestPolicy.h" |
| 59 #include "third_party/WebKit/public/web/WebSandboxFlags.h" | 61 #include "third_party/WebKit/public/web/WebSandboxFlags.h" |
| 60 #include "ui/base/page_transition_types.h" | 62 #include "ui/base/page_transition_types.h" |
| 61 | 63 |
| 62 namespace content { | 64 namespace content { |
| 63 namespace { | 65 namespace { |
| 64 | 66 |
| 65 // Helper to check that the provided RenderProcessHost received exactly one | 67 // Helper to check that the provided RenderProcessHost received exactly one |
| 66 // page focus message with the provided focus and routing ID values. | 68 // page focus message with the provided focus and routing ID values. |
| 67 void VerifyPageFocusMessage(MockRenderProcessHost* rph, | 69 void VerifyPageFocusMessage(MockRenderProcessHost* rph, |
| (...skipping 3092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3160 EXPECT_NE(initial_rfh, main_test_rfh()); | 3162 EXPECT_NE(initial_rfh, main_test_rfh()); |
| 3161 ASSERT_FALSE(delete_observer.deleted()); | 3163 ASSERT_FALSE(delete_observer.deleted()); |
| 3162 EXPECT_FALSE(initial_rfh->is_active()); | 3164 EXPECT_FALSE(initial_rfh->is_active()); |
| 3163 | 3165 |
| 3164 // The initial RFH receives a DidStartProvisionalLoad IPC. It should not | 3166 // The initial RFH receives a DidStartProvisionalLoad IPC. It should not |
| 3165 // create a NavigationHandle. | 3167 // create a NavigationHandle. |
| 3166 initial_rfh->SimulateNavigationStart(kUrl3); | 3168 initial_rfh->SimulateNavigationStart(kUrl3); |
| 3167 EXPECT_FALSE(initial_rfh->navigation_handle()); | 3169 EXPECT_FALSE(initial_rfh->navigation_handle()); |
| 3168 } | 3170 } |
| 3169 | 3171 |
| 3172 // Integration tests for feature policy setup and querying through a RFH. These | |
| 3173 // tests are not meant to cover every edge case as the FeaturePolicy class | |
| 3174 // itself is tested thoroughly in feature_policy_unittest.cc. Instead they are | |
| 3175 // meant to ensure that integration with RenderFrameHost works correctly. | |
| 3176 class RenderFrameFeaturePolicyTest : public content::RenderViewHostTestHarness { | |
|
alexmos
2017/05/16 21:40:05
After looking at this and also consulting with cre
raymes
2017/05/17 05:46:41
I like the idea of a separate test file :) (giant
| |
| 3177 protected: | |
| 3178 static constexpr const char* kOrigin1 = "https://google.com"; | |
| 3179 static constexpr const char* kOrigin2 = "https://maps.google.com"; | |
| 3180 static constexpr const char* kOrigin3 = "https://example.com"; | |
| 3181 static constexpr const char* kOrigin4 = "https://test.com"; | |
| 3182 | |
| 3183 static const blink::WebFeaturePolicyFeature kDefaultEnabledFeature = | |
| 3184 blink::WebFeaturePolicyFeature::kDocumentWrite; | |
| 3185 static const blink::WebFeaturePolicyFeature kDefaultSelfFeature = | |
| 3186 blink::WebFeaturePolicyFeature::kGeolocation; | |
| 3187 | |
| 3188 RenderFrameHost* GetMainRFH(const char* origin) { | |
| 3189 RenderFrameHost* result = web_contents()->GetMainFrame(); | |
| 3190 RenderFrameHostTester::For(result)->InitializeRenderFrameIfNeeded(); | |
| 3191 RenderFrameHostTester::For(result)->SimulateNavigationCommit(GURL(origin)); | |
| 3192 return result; | |
| 3193 } | |
| 3194 | |
| 3195 RenderFrameHost* AddChildRFH(RenderFrameHost* parent, const char* origin) { | |
| 3196 RenderFrameHost* result = | |
| 3197 RenderFrameHostTester::For(parent)->AppendChild(""); | |
| 3198 RenderFrameHostTester::For(result)->InitializeRenderFrameIfNeeded(); | |
| 3199 RenderFrameHostTester::For(result)->SimulateNavigationCommit(GURL(origin)); | |
| 3200 return result; | |
| 3201 } | |
| 3202 | |
| 3203 void SetHeaderPolicy(RenderFrameHost* rfh, | |
| 3204 blink::WebFeaturePolicyFeature feature, | |
| 3205 const std::vector<std::string>& origins) { | |
| 3206 static_cast<TestRenderFrameHost*>(rfh)->OnDidSetFeaturePolicyHeader( | |
| 3207 CreateFPHeader(feature, origins)); | |
| 3208 } | |
| 3209 | |
| 3210 void SetContainerPolicy(RenderFrameHost* parent, | |
| 3211 RenderFrameHost* child, | |
| 3212 blink::WebFeaturePolicyFeature feature, | |
| 3213 const std::vector<std::string>& origins) { | |
| 3214 static_cast<TestRenderFrameHost*>(parent)->OnDidChangeFramePolicy( | |
| 3215 child->GetRoutingID(), blink::WebSandboxFlags(), | |
| 3216 CreateFPHeader(feature, origins)); | |
| 3217 } | |
| 3218 | |
| 3219 private: | |
| 3220 ParsedFeaturePolicyHeader CreateFPHeader( | |
| 3221 blink::WebFeaturePolicyFeature feature, | |
| 3222 const std::vector<std::string>& origins) { | |
| 3223 ParsedFeaturePolicyHeader result(1); | |
| 3224 result[0].feature = feature; | |
| 3225 result[0].matches_all_origins = false; | |
| 3226 for (const std::string& origin : origins) | |
| 3227 result[0].origins.push_back(url::Origin(GURL(origin))); | |
| 3228 return result; | |
| 3229 } | |
| 3230 }; | |
| 3231 | |
| 3232 TEST_F(RenderFrameFeaturePolicyTest, DefaultPolicy) { | |
|
alexmos
2017/05/16 21:40:04
I'd include Host in the name, i.e. RenderFrameHost
raymes
2017/05/17 05:46:41
Oops, done.
| |
| 3233 RenderFrameHost* parent = GetMainRFH(kOrigin1); | |
| 3234 RenderFrameHost* child = AddChildRFH(parent, kOrigin2); | |
| 3235 | |
| 3236 EXPECT_TRUE(parent->IsFeatureEnabled(kDefaultEnabledFeature)); | |
| 3237 EXPECT_TRUE(parent->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3238 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultEnabledFeature)); | |
| 3239 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3240 } | |
| 3241 | |
| 3242 TEST_F(RenderFrameFeaturePolicyTest, HeaderPolicy) { | |
| 3243 RenderFrameHost* parent = GetMainRFH(kOrigin1); | |
| 3244 | |
| 3245 // Enable the feature for the child in the parent frame. | |
| 3246 SetHeaderPolicy(parent, kDefaultSelfFeature, {kOrigin1, kOrigin2}); | |
| 3247 | |
| 3248 // Create the child. | |
| 3249 RenderFrameHost* child = AddChildRFH(parent, kOrigin2); | |
| 3250 | |
| 3251 EXPECT_TRUE(parent->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3252 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3253 | |
| 3254 // Set an empty whitelist in the child to test that the policies combine | |
| 3255 // correctly. | |
| 3256 SetHeaderPolicy(child, kDefaultSelfFeature, {}); | |
| 3257 | |
| 3258 EXPECT_TRUE(parent->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3259 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3260 | |
| 3261 // Re-enable the feature in the child. | |
| 3262 SetHeaderPolicy(child, kDefaultSelfFeature, {kOrigin2}); | |
| 3263 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3264 | |
| 3265 // Navigate the child. Check that the feature is disabled. | |
| 3266 RenderFrameHostTester::For(child)->SimulateNavigationCommit(GURL(kOrigin3)); | |
| 3267 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3268 } | |
| 3269 | |
| 3270 TEST_F(RenderFrameFeaturePolicyTest, ContainerPolicy) { | |
| 3271 RenderFrameHost* parent = GetMainRFH(kOrigin1); | |
| 3272 RenderFrameHost* child = AddChildRFH(parent, kOrigin2); | |
| 3273 | |
| 3274 // Set a container policy on origin 3 to give it the feature. It should not | |
| 3275 // be enabled because container policy will only take effect after navigation. | |
| 3276 SetContainerPolicy(parent, child, kDefaultSelfFeature, {kOrigin2, kOrigin3}); | |
| 3277 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3278 | |
| 3279 // Navigate the child so that the container policy takes effect. | |
| 3280 RenderFrameHostTester::For(child)->SimulateNavigationCommit(GURL(kOrigin3)); | |
| 3281 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3282 | |
| 3283 // Navigate the child again, the feature should not be enabled. | |
| 3284 RenderFrameHostTester::For(child)->SimulateNavigationCommit(GURL(kOrigin4)); | |
| 3285 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3286 } | |
| 3287 | |
| 3288 TEST_F(RenderFrameFeaturePolicyTest, HeaderAndContainerPolicy) { | |
| 3289 RenderFrameHost* parent = GetMainRFH(kOrigin1); | |
| 3290 | |
| 3291 // Set a header policy and container policy. Check that they both take effect. | |
| 3292 SetHeaderPolicy(parent, kDefaultSelfFeature, {kOrigin1, kOrigin2}); | |
| 3293 | |
| 3294 RenderFrameHost* child = AddChildRFH(parent, kOrigin2); | |
| 3295 SetContainerPolicy(parent, child, kDefaultSelfFeature, {kOrigin3}); | |
| 3296 | |
| 3297 // The feature should be enabled in kOrigin2, kOrigin3 but not kOrigin4. | |
| 3298 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3299 RenderFrameHostTester::For(child)->SimulateNavigationCommit(GURL(kOrigin3)); | |
| 3300 EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3301 RenderFrameHostTester::For(child)->SimulateNavigationCommit(GURL(kOrigin4)); | |
| 3302 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3303 | |
| 3304 // Change the header policy to turn off the feature. It should be disabled in | |
| 3305 // all children. | |
| 3306 SetHeaderPolicy(parent, kDefaultSelfFeature, {}); | |
|
alexmos
2017/05/16 21:40:05
Is this testing a scenario that's actually possibl
raymes
2017/05/17 05:46:41
It's true - I was cheating :) I changed it to "Ref
alexmos
2017/05/17 22:48:49
Will that work across multiple documents in the sa
| |
| 3307 RenderFrameHostTester::For(child)->SimulateNavigationCommit(GURL(kOrigin2)); | |
| 3308 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3309 RenderFrameHostTester::For(child)->SimulateNavigationCommit(GURL(kOrigin3)); | |
| 3310 EXPECT_FALSE(child->IsFeatureEnabled(kDefaultSelfFeature)); | |
| 3311 } | |
| 3312 | |
| 3170 } // namespace content | 3313 } // namespace content |
| OLD | NEW |