1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/web_request/web_request_permissions.h" 6 7 #include "base/message_loop/message_loop.h" 8 #include "chrome/common/extensions/extension_constants.h" 9 #include "chrome/common/extensions/extension_test_util.h" 10 #include "chrome/test/base/testing_profile.h" 11 #include "content/public/browser/resource_request_info.h" 12 #include "content/public/test/test_browser_thread_bundle.h" 13 #include "extensions/browser/info_map.h" 14 #include "ipc/ipc_message.h" 15 #include "net/base/request_priority.h" 16 #include "net/url_request/url_request_test_util.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 19 using content::ResourceRequestInfo; 20 using extensions::Extension; 21 using extensions::Manifest; 22 using extension_test_util::LoadManifestUnchecked; 23 24 class ExtensionWebRequestHelpersTestWithThreadsTest : public testing::Test { 25 public: 26 ExtensionWebRequestHelpersTestWithThreadsTest() 27 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {} 28 29 protected: 30 virtual void SetUp() OVERRIDE; 31 32 protected: 33 net::TestURLRequestContext context; 34 35 // This extension has Web Request permissions, but no host permission. 36 scoped_refptr<Extension> permissionless_extension_; 37 // This extension has Web Request permissions, and *.com a host permission. 38 scoped_refptr<Extension> com_extension_; 39 scoped_refptr<extensions::InfoMap> extension_info_map_; 40 41 private: 42 content::TestBrowserThreadBundle thread_bundle_; 43 }; 44 45 void ExtensionWebRequestHelpersTestWithThreadsTest::SetUp() { 46 testing::Test::SetUp(); 47 48 std::string error; 49 permissionless_extension_ = LoadManifestUnchecked("permissions", 50 "web_request_no_host.json", 51 Manifest::INVALID_LOCATION, 52 Extension::NO_FLAGS, 53 "ext_id_1", 54 &error); 55 ASSERT_TRUE(permissionless_extension_.get()) << error; 56 com_extension_ = 57 LoadManifestUnchecked("permissions", 58 "web_request_com_host_permissions.json", 59 Manifest::INVALID_LOCATION, 60 Extension::NO_FLAGS, 61 "ext_id_2", 62 &error); 63 ASSERT_TRUE(com_extension_.get()) << error; 64 extension_info_map_ = new extensions::InfoMap; 65 extension_info_map_->AddExtension(permissionless_extension_.get(), 66 base::Time::Now(), 67 false /*incognito_enabled*/, 68 false /*notifications_disabled*/); 69 extension_info_map_->AddExtension( 70 com_extension_.get(), 71 base::Time::Now(), 72 false /*incognito_enabled*/, 73 false /*notifications_disabled*/); 74 } 75 76 TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest, TestHideRequestForURL) { 77 net::TestURLRequestContext context; 78 const char* sensitive_urls[] = { 79 "http://clients2.google.com", 80 "http://clients22.google.com", 81 "https://clients2.google.com", 82 "http://clients2.google.com/service/update2/crx", 83 "https://clients.google.com", 84 "https://test.clients.google.com", 85 "https://clients2.google.com/service/update2/crx", 86 "http://www.gstatic.com/chrome/extensions/blacklist", 87 "https://www.gstatic.com/chrome/extensions/blacklist", 88 "notregisteredscheme://www.foobar.com", 89 "https://chrome.google.com/webstore/", 90 "https://chrome.google.com/webstore/" 91 "inlineinstall/detail/kcnhkahnjcbndmmehfkdnkjomaanaooo" 92 }; 93 const char* non_sensitive_urls[] = { 94 "http://www.google.com/" 95 }; 96 const int kSigninProcessId = 99; 97 extension_info_map_->SetSigninProcess(kSigninProcessId); 98 99 // Check that requests are rejected based on the destination 100 for (size_t i = 0; i < arraysize(sensitive_urls); ++i) { 101 GURL sensitive_url(sensitive_urls[i]); 102 net::TestURLRequest request( 103 sensitive_url, net::DEFAULT_PRIORITY, NULL, &context); 104 EXPECT_TRUE( 105 WebRequestPermissions::HideRequest(extension_info_map_.get(), &request)) 106 << sensitive_urls[i]; 107 } 108 // Check that requests are accepted if they don't touch sensitive urls. 109 for (size_t i = 0; i < arraysize(non_sensitive_urls); ++i) { 110 GURL non_sensitive_url(non_sensitive_urls[i]); 111 net::TestURLRequest request( 112 non_sensitive_url, net::DEFAULT_PRIORITY, NULL, &context); 113 EXPECT_FALSE( 114 WebRequestPermissions::HideRequest(extension_info_map_.get(), &request)) 115 << non_sensitive_urls[i]; 116 } 117 118 // Check protection of requests originating from the frame showing the Chrome 119 // WebStore. 120 // Normally this request is not protected: 121 GURL non_sensitive_url("http://www.google.com/test.js"); 122 net::TestURLRequest non_sensitive_request( 123 non_sensitive_url, net::DEFAULT_PRIORITY, NULL, &context); 124 EXPECT_FALSE(WebRequestPermissions::HideRequest(extension_info_map_.get(), 125 &non_sensitive_request)); 126 // If the origin is labeled by the WebStoreAppId, it becomes protected. 127 { 128 int process_id = 42; 129 int site_instance_id = 23; 130 int view_id = 17; 131 net::TestURLRequest sensitive_request( 132 non_sensitive_url, net::DEFAULT_PRIORITY, NULL, &context); 133 ResourceRequestInfo::AllocateForTesting( 134 &sensitive_request, ResourceType::SCRIPT, NULL, 135 process_id, view_id, MSG_ROUTING_NONE, false); 136 extension_info_map_->RegisterExtensionProcess( 137 extension_misc::kWebStoreAppId, process_id, site_instance_id); 138 EXPECT_TRUE(WebRequestPermissions::HideRequest(extension_info_map_.get(), 139 &sensitive_request)); 140 } 141 // If the process is the signin process, it becomes protected. 142 { 143 int process_id = kSigninProcessId; 144 int view_id = 19; 145 net::TestURLRequest sensitive_request( 146 non_sensitive_url, net::DEFAULT_PRIORITY, NULL, &context); 147 ResourceRequestInfo::AllocateForTesting( 148 &sensitive_request, ResourceType::SCRIPT, NULL, 149 process_id, view_id, MSG_ROUTING_NONE, false); 150 EXPECT_TRUE(WebRequestPermissions::HideRequest(extension_info_map_.get(), 151 &sensitive_request)); 152 } 153 } 154 155 TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest, 156 TestCanExtensionAccessURL_HostPermissions) { 157 net::TestURLRequest request( 158 GURL("http://example.com"), net::DEFAULT_PRIORITY, NULL, &context); 159 160 EXPECT_TRUE(WebRequestPermissions::CanExtensionAccessURL( 161 extension_info_map_.get(), 162 permissionless_extension_->id(), 163 request.url(), 164 false /*crosses_incognito*/, 165 WebRequestPermissions::DO_NOT_CHECK_HOST)); 166 EXPECT_FALSE(WebRequestPermissions::CanExtensionAccessURL( 167 extension_info_map_.get(), 168 permissionless_extension_->id(), 169 request.url(), 170 false /*crosses_incognito*/, 171 WebRequestPermissions::REQUIRE_HOST_PERMISSION)); 172 EXPECT_TRUE(WebRequestPermissions::CanExtensionAccessURL( 173 extension_info_map_.get(), 174 com_extension_->id(), 175 request.url(), 176 false /*crosses_incognito*/, 177 WebRequestPermissions::REQUIRE_HOST_PERMISSION)); 178 EXPECT_FALSE(WebRequestPermissions::CanExtensionAccessURL( 179 extension_info_map_.get(), 180 com_extension_->id(), 181 request.url(), 182 false /*crosses_incognito*/, 183 WebRequestPermissions::REQUIRE_ALL_URLS)); 184 } 185