| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
| 6 #include "base/run_loop.h" | 6 #include "base/run_loop.h" |
| 7 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 7 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
| 8 #include "chrome/browser/safe_browsing/safe_browsing_util.h" | 8 #include "chrome/browser/safe_browsing/safe_browsing_util.h" |
| 9 #include "chrome/browser/safe_browsing/ui_manager.h" | 9 #include "chrome/browser/safe_browsing/ui_manager.h" |
| 10 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 10 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| 11 #include "chrome/test/base/testing_profile.h" | 11 #include "chrome/test/base/testing_profile.h" |
| 12 #include "content/public/browser/render_process_host.h" | 12 #include "content/public/browser/render_process_host.h" |
| 13 #include "content/public/browser/render_view_host.h" | 13 #include "content/public/browser/render_view_host.h" |
| 14 #include "content/public/browser/web_contents.h" | 14 #include "content/public/browser/web_contents.h" |
| 15 #include "content/public/test/test_browser_thread_bundle.h" | 15 #include "content/public/test/test_browser_thread_bundle.h" |
| 16 #include "content/public/test/web_contents_tester.h" | 16 #include "content/public/test/web_contents_tester.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "url/gurl.h" | 18 #include "url/gurl.h" |
| 19 | 19 |
| 20 using content::BrowserThread; | 20 using content::BrowserThread; |
| 21 | 21 |
| 22 static const char* kGoodURL = "https://www.good.com"; | 22 static const char* kGoodURL = "https://www.good.com"; |
| 23 static const char* kBadURL = "https://www.malware.com"; | 23 static const char* kBadURL = "https://www.malware.com"; |
| 24 static const char* kBadURLWithPath = "https://www.malware.com/index.html"; | 24 static const char* kBadURLWithPath = "https://www.malware.com/index.html"; |
| 25 static const char* kAnotherBadURL = "https://www.badware.com"; |
| 26 static const char* kLandingURL = "https://www.landing.com"; |
| 25 | 27 |
| 26 namespace safe_browsing { | 28 namespace safe_browsing { |
| 27 | 29 |
| 28 class SafeBrowsingCallbackWaiter { | 30 class SafeBrowsingCallbackWaiter { |
| 29 public: | 31 public: |
| 30 SafeBrowsingCallbackWaiter() {} | 32 SafeBrowsingCallbackWaiter() {} |
| 31 | 33 |
| 32 bool callback_called() const { return callback_called_; } | 34 bool callback_called() const { return callback_called_; } |
| 33 bool proceed() const { return proceed_; } | 35 bool proceed() const { return proceed_; } |
| 34 | 36 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); } | 74 void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); } |
| 73 | 75 |
| 74 bool IsWhitelisted(SafeBrowsingUIManager::UnsafeResource resource) { | 76 bool IsWhitelisted(SafeBrowsingUIManager::UnsafeResource resource) { |
| 75 return ui_manager_->IsWhitelisted(resource); | 77 return ui_manager_->IsWhitelisted(resource); |
| 76 } | 78 } |
| 77 | 79 |
| 78 void AddToWhitelist(SafeBrowsingUIManager::UnsafeResource resource) { | 80 void AddToWhitelist(SafeBrowsingUIManager::UnsafeResource resource) { |
| 79 ui_manager_->AddToWhitelist(resource); | 81 ui_manager_->AddToWhitelist(resource); |
| 80 } | 82 } |
| 81 | 83 |
| 82 SafeBrowsingUIManager::UnsafeResource MakeUnsafeResource(const char* url) { | 84 SafeBrowsingUIManager::UnsafeResource MakeUnsafeResource( |
| 85 const char* url, |
| 86 bool is_subresource) { |
| 83 SafeBrowsingUIManager::UnsafeResource resource; | 87 SafeBrowsingUIManager::UnsafeResource resource; |
| 84 resource.url = GURL(url); | 88 resource.url = GURL(url); |
| 89 resource.is_subresource = is_subresource; |
| 85 resource.render_process_host_id = | 90 resource.render_process_host_id = |
| 86 web_contents()->GetRenderProcessHost()->GetID(); | 91 web_contents()->GetRenderProcessHost()->GetID(); |
| 87 resource.render_view_id = | 92 resource.render_view_id = |
| 88 web_contents()->GetRenderViewHost()->GetRoutingID(); | 93 web_contents()->GetRenderViewHost()->GetRoutingID(); |
| 89 resource.threat_type = SB_THREAT_TYPE_URL_MALWARE; | 94 resource.threat_type = SB_THREAT_TYPE_URL_MALWARE; |
| 90 return resource; | 95 return resource; |
| 91 } | 96 } |
| 92 | 97 |
| 93 SafeBrowsingUIManager::UnsafeResource MakeUnsafeResourceAndNavigate( | 98 SafeBrowsingUIManager::UnsafeResource MakeUnsafeResourceAndStartNavigation( |
| 94 const char* url) { | 99 const char* url) { |
| 95 SafeBrowsingUIManager::UnsafeResource resource = MakeUnsafeResource(url); | 100 SafeBrowsingUIManager::UnsafeResource resource = |
| 101 MakeUnsafeResource(url, false /* is_subresource */); |
| 96 | 102 |
| 97 // The WC doesn't have a URL without a navigation. Normally the | 103 // The WC doesn't have a URL without a navigation. A main-frame malware |
| 98 // interstitial would provide this instead of a fully committed navigation. | 104 // unsafe resource must be a pending navigation. |
| 99 EXPECT_FALSE(IsWhitelisted(resource)); | 105 content::WebContentsTester::For(web_contents())->StartNavigation(GURL(url)); |
| 100 NavigateAndCommit(GURL(url)); | |
| 101 return resource; | 106 return resource; |
| 102 } | 107 } |
| 103 | 108 |
| 104 void SimulateBlockingPageDone( | 109 void SimulateBlockingPageDone( |
| 105 const std::vector<SafeBrowsingUIManager::UnsafeResource>& resources, | 110 const std::vector<SafeBrowsingUIManager::UnsafeResource>& resources, |
| 106 bool proceed) { | 111 bool proceed) { |
| 107 ui_manager_->OnBlockingPageDone(resources, proceed); | 112 ui_manager_->OnBlockingPageDone(resources, proceed); |
| 108 } | 113 } |
| 109 | 114 |
| 110 private: | 115 private: |
| 111 scoped_refptr<SafeBrowsingUIManager> ui_manager_; | 116 scoped_refptr<SafeBrowsingUIManager> ui_manager_; |
| 112 }; | 117 }; |
| 113 | 118 |
| 114 TEST_F(SafeBrowsingUIManagerTest, Whitelist) { | 119 TEST_F(SafeBrowsingUIManagerTest, Whitelist) { |
| 115 SafeBrowsingUIManager::UnsafeResource resource = | 120 SafeBrowsingUIManager::UnsafeResource resource = |
| 116 MakeUnsafeResourceAndNavigate(kBadURL); | 121 MakeUnsafeResourceAndStartNavigation(kBadURL); |
| 117 AddToWhitelist(resource); | 122 AddToWhitelist(resource); |
| 118 EXPECT_TRUE(IsWhitelisted(resource)); | 123 EXPECT_TRUE(IsWhitelisted(resource)); |
| 119 } | 124 } |
| 120 | 125 |
| 121 TEST_F(SafeBrowsingUIManagerTest, WhitelistIgnoresSitesNotAdded) { | 126 TEST_F(SafeBrowsingUIManagerTest, WhitelistIgnoresSitesNotAdded) { |
| 122 SafeBrowsingUIManager::UnsafeResource resource = | 127 SafeBrowsingUIManager::UnsafeResource resource = |
| 123 MakeUnsafeResourceAndNavigate(kGoodURL); | 128 MakeUnsafeResourceAndStartNavigation(kGoodURL); |
| 124 EXPECT_FALSE(IsWhitelisted(resource)); | 129 EXPECT_FALSE(IsWhitelisted(resource)); |
| 125 } | 130 } |
| 126 | 131 |
| 127 TEST_F(SafeBrowsingUIManagerTest, WhitelistIgnoresPath) { | 132 TEST_F(SafeBrowsingUIManagerTest, WhitelistIgnoresPath) { |
| 128 SafeBrowsingUIManager::UnsafeResource resource = | 133 SafeBrowsingUIManager::UnsafeResource resource = |
| 129 MakeUnsafeResourceAndNavigate(kBadURL); | 134 MakeUnsafeResourceAndStartNavigation(kBadURL); |
| 130 AddToWhitelist(resource); | 135 AddToWhitelist(resource); |
| 131 EXPECT_TRUE(IsWhitelisted(resource)); | 136 EXPECT_TRUE(IsWhitelisted(resource)); |
| 132 | 137 |
| 138 content::WebContentsTester::For(web_contents())->CommitPendingNavigation(); |
| 139 |
| 133 SafeBrowsingUIManager::UnsafeResource resource_path = | 140 SafeBrowsingUIManager::UnsafeResource resource_path = |
| 134 MakeUnsafeResource(kBadURLWithPath); | 141 MakeUnsafeResourceAndStartNavigation(kBadURLWithPath); |
| 135 EXPECT_TRUE(IsWhitelisted(resource_path)); | 142 EXPECT_TRUE(IsWhitelisted(resource_path)); |
| 136 } | 143 } |
| 137 | 144 |
| 138 TEST_F(SafeBrowsingUIManagerTest, WhitelistIgnoresThreatType) { | 145 TEST_F(SafeBrowsingUIManagerTest, WhitelistIgnoresThreatType) { |
| 139 SafeBrowsingUIManager::UnsafeResource resource = | 146 SafeBrowsingUIManager::UnsafeResource resource = |
| 140 MakeUnsafeResourceAndNavigate(kBadURL); | 147 MakeUnsafeResourceAndStartNavigation(kBadURL); |
| 141 AddToWhitelist(resource); | 148 AddToWhitelist(resource); |
| 142 EXPECT_TRUE(IsWhitelisted(resource)); | 149 EXPECT_TRUE(IsWhitelisted(resource)); |
| 143 | 150 |
| 144 SafeBrowsingUIManager::UnsafeResource resource_phishing = | 151 SafeBrowsingUIManager::UnsafeResource resource_phishing = |
| 145 MakeUnsafeResource(kBadURL); | 152 MakeUnsafeResource(kBadURL, false /* is_subresource */); |
| 146 resource_phishing.threat_type = SB_THREAT_TYPE_URL_PHISHING; | 153 resource_phishing.threat_type = SB_THREAT_TYPE_URL_PHISHING; |
| 147 EXPECT_TRUE(IsWhitelisted(resource_phishing)); | 154 EXPECT_TRUE(IsWhitelisted(resource_phishing)); |
| 148 } | 155 } |
| 149 | 156 |
| 157 TEST_F(SafeBrowsingUIManagerTest, WhitelistWithUnrelatedPendingLoad) { |
| 158 // Commit load of landing page. |
| 159 NavigateAndCommit(GURL(kLandingURL)); |
| 160 { |
| 161 // Simulate subresource malware hit on the landing page. |
| 162 SafeBrowsingUIManager::UnsafeResource resource = |
| 163 MakeUnsafeResource(kBadURL, true /* is_subresource */); |
| 164 |
| 165 // Start pending load to unrelated site. |
| 166 content::WebContentsTester::For(web_contents()) |
| 167 ->StartNavigation(GURL(kGoodURL)); |
| 168 |
| 169 // Whitelist the resource on the landing page. |
| 170 AddToWhitelist(resource); |
| 171 EXPECT_TRUE(IsWhitelisted(resource)); |
| 172 } |
| 173 |
| 174 // Commit the pending load of unrelated site. |
| 175 content::WebContentsTester::For(web_contents())->CommitPendingNavigation(); |
| 176 { |
| 177 // The unrelated site is not on the whitelist, even if the same subresource |
| 178 // was on it. |
| 179 SafeBrowsingUIManager::UnsafeResource resource = |
| 180 MakeUnsafeResource(kBadURL, true /* is_subresource */); |
| 181 EXPECT_FALSE(IsWhitelisted(resource)); |
| 182 } |
| 183 |
| 184 // Navigate back to the original landing url. |
| 185 NavigateAndCommit(GURL(kLandingURL)); |
| 186 { |
| 187 SafeBrowsingUIManager::UnsafeResource resource = |
| 188 MakeUnsafeResource(kBadURL, true /* is_subresource */); |
| 189 // Original resource url is whitelisted. |
| 190 EXPECT_TRUE(IsWhitelisted(resource)); |
| 191 } |
| 192 { |
| 193 // A different malware subresource on the same page is also whitelisted. |
| 194 // (The whitelist is by the page url, not the resource url.) |
| 195 SafeBrowsingUIManager::UnsafeResource resource2 = |
| 196 MakeUnsafeResource(kAnotherBadURL, true /* is_subresource */); |
| 197 EXPECT_TRUE(IsWhitelisted(resource2)); |
| 198 } |
| 199 } |
| 200 |
| 150 TEST_F(SafeBrowsingUIManagerTest, UICallbackProceed) { | 201 TEST_F(SafeBrowsingUIManagerTest, UICallbackProceed) { |
| 151 SafeBrowsingUIManager::UnsafeResource resource = | 202 SafeBrowsingUIManager::UnsafeResource resource = |
| 152 MakeUnsafeResourceAndNavigate(kBadURL); | 203 MakeUnsafeResourceAndStartNavigation(kBadURL); |
| 153 SafeBrowsingCallbackWaiter waiter; | 204 SafeBrowsingCallbackWaiter waiter; |
| 154 resource.callback = | 205 resource.callback = |
| 155 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDone, | 206 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDone, |
| 156 base::Unretained(&waiter)); | 207 base::Unretained(&waiter)); |
| 157 resource.callback_thread = | 208 resource.callback_thread = |
| 158 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); | 209 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); |
| 159 std::vector<SafeBrowsingUIManager::UnsafeResource> resources; | 210 std::vector<SafeBrowsingUIManager::UnsafeResource> resources; |
| 160 resources.push_back(resource); | 211 resources.push_back(resource); |
| 161 SimulateBlockingPageDone(resources, true); | 212 SimulateBlockingPageDone(resources, true); |
| 162 EXPECT_TRUE(IsWhitelisted(resource)); | 213 EXPECT_TRUE(IsWhitelisted(resource)); |
| 163 waiter.WaitForCallback(); | 214 waiter.WaitForCallback(); |
| 164 EXPECT_TRUE(waiter.callback_called()); | 215 EXPECT_TRUE(waiter.callback_called()); |
| 165 EXPECT_TRUE(waiter.proceed()); | 216 EXPECT_TRUE(waiter.proceed()); |
| 166 } | 217 } |
| 167 | 218 |
| 168 TEST_F(SafeBrowsingUIManagerTest, UICallbackDontProceed) { | 219 TEST_F(SafeBrowsingUIManagerTest, UICallbackDontProceed) { |
| 169 SafeBrowsingUIManager::UnsafeResource resource = | 220 SafeBrowsingUIManager::UnsafeResource resource = |
| 170 MakeUnsafeResourceAndNavigate(kBadURL); | 221 MakeUnsafeResourceAndStartNavigation(kBadURL); |
| 171 SafeBrowsingCallbackWaiter waiter; | 222 SafeBrowsingCallbackWaiter waiter; |
| 172 resource.callback = | 223 resource.callback = |
| 173 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDone, | 224 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDone, |
| 174 base::Unretained(&waiter)); | 225 base::Unretained(&waiter)); |
| 175 resource.callback_thread = | 226 resource.callback_thread = |
| 176 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); | 227 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); |
| 177 std::vector<SafeBrowsingUIManager::UnsafeResource> resources; | 228 std::vector<SafeBrowsingUIManager::UnsafeResource> resources; |
| 178 resources.push_back(resource); | 229 resources.push_back(resource); |
| 179 SimulateBlockingPageDone(resources, false); | 230 SimulateBlockingPageDone(resources, false); |
| 180 EXPECT_FALSE(IsWhitelisted(resource)); | 231 EXPECT_FALSE(IsWhitelisted(resource)); |
| 181 waiter.WaitForCallback(); | 232 waiter.WaitForCallback(); |
| 182 EXPECT_TRUE(waiter.callback_called()); | 233 EXPECT_TRUE(waiter.callback_called()); |
| 183 EXPECT_FALSE(waiter.proceed()); | 234 EXPECT_FALSE(waiter.proceed()); |
| 184 } | 235 } |
| 185 | 236 |
| 186 TEST_F(SafeBrowsingUIManagerTest, IOCallbackProceed) { | 237 TEST_F(SafeBrowsingUIManagerTest, IOCallbackProceed) { |
| 187 SafeBrowsingUIManager::UnsafeResource resource = | 238 SafeBrowsingUIManager::UnsafeResource resource = |
| 188 MakeUnsafeResourceAndNavigate(kBadURL); | 239 MakeUnsafeResourceAndStartNavigation(kBadURL); |
| 189 SafeBrowsingCallbackWaiter waiter; | 240 SafeBrowsingCallbackWaiter waiter; |
| 190 resource.callback = | 241 resource.callback = |
| 191 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO, | 242 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO, |
| 192 base::Unretained(&waiter)); | 243 base::Unretained(&waiter)); |
| 193 resource.callback_thread = | 244 resource.callback_thread = |
| 194 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); | 245 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); |
| 195 std::vector<SafeBrowsingUIManager::UnsafeResource> resources; | 246 std::vector<SafeBrowsingUIManager::UnsafeResource> resources; |
| 196 resources.push_back(resource); | 247 resources.push_back(resource); |
| 197 SimulateBlockingPageDone(resources, true); | 248 SimulateBlockingPageDone(resources, true); |
| 198 EXPECT_TRUE(IsWhitelisted(resource)); | 249 EXPECT_TRUE(IsWhitelisted(resource)); |
| 199 waiter.WaitForCallback(); | 250 waiter.WaitForCallback(); |
| 200 EXPECT_TRUE(waiter.callback_called()); | 251 EXPECT_TRUE(waiter.callback_called()); |
| 201 EXPECT_TRUE(waiter.proceed()); | 252 EXPECT_TRUE(waiter.proceed()); |
| 202 } | 253 } |
| 203 | 254 |
| 204 TEST_F(SafeBrowsingUIManagerTest, IOCallbackDontProceed) { | 255 TEST_F(SafeBrowsingUIManagerTest, IOCallbackDontProceed) { |
| 205 SafeBrowsingUIManager::UnsafeResource resource = | 256 SafeBrowsingUIManager::UnsafeResource resource = |
| 206 MakeUnsafeResourceAndNavigate(kBadURL); | 257 MakeUnsafeResourceAndStartNavigation(kBadURL); |
| 207 SafeBrowsingCallbackWaiter waiter; | 258 SafeBrowsingCallbackWaiter waiter; |
| 208 resource.callback = | 259 resource.callback = |
| 209 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO, | 260 base::Bind(&SafeBrowsingCallbackWaiter::OnBlockingPageDoneOnIO, |
| 210 base::Unretained(&waiter)); | 261 base::Unretained(&waiter)); |
| 211 resource.callback_thread = | 262 resource.callback_thread = |
| 212 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); | 263 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); |
| 213 std::vector<SafeBrowsingUIManager::UnsafeResource> resources; | 264 std::vector<SafeBrowsingUIManager::UnsafeResource> resources; |
| 214 resources.push_back(resource); | 265 resources.push_back(resource); |
| 215 SimulateBlockingPageDone(resources, false); | 266 SimulateBlockingPageDone(resources, false); |
| 216 EXPECT_FALSE(IsWhitelisted(resource)); | 267 EXPECT_FALSE(IsWhitelisted(resource)); |
| 217 waiter.WaitForCallback(); | 268 waiter.WaitForCallback(); |
| 218 EXPECT_TRUE(waiter.callback_called()); | 269 EXPECT_TRUE(waiter.callback_called()); |
| 219 EXPECT_FALSE(waiter.proceed()); | 270 EXPECT_FALSE(waiter.proceed()); |
| 220 } | 271 } |
| 221 | 272 |
| 222 } // namespace safe_browsing | 273 } // namespace safe_browsing |
| OLD | NEW |