| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2009 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/renderer_host/test_render_view_host.h" |
| 6 |
| 7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" |
| 8 #include "chrome/browser/tab_contents/navigation_entry.h" |
| 9 #include "chrome/common/render_messages.h" |
| 10 |
| 11 static const char* kGoogleURL = "http://www.google.com/"; |
| 12 static const char* kGoodURL = "http://www.goodguys.com/"; |
| 13 static const char* kBadURL = "http://www.badguys.com/"; |
| 14 static const char* kBadURL2 = "http://www.badguys2.com/"; |
| 15 static const char* kBadURL3 = "http://www.badguys3.com/"; |
| 16 |
| 17 static void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params, |
| 18 int page_id, |
| 19 const GURL& url) { |
| 20 params->page_id = page_id; |
| 21 params->url = url; |
| 22 params->referrer = GURL::EmptyGURL(); |
| 23 params->transition = PageTransition::TYPED; |
| 24 params->redirects = std::vector<GURL>(); |
| 25 params->should_update_history = false; |
| 26 params->searchable_form_url = GURL::EmptyGURL(); |
| 27 params->searchable_form_element_name = std::wstring(); |
| 28 params->searchable_form_encoding = std::string(); |
| 29 params->password_form = PasswordForm(); |
| 30 params->security_info = std::string(); |
| 31 params->gesture = NavigationGestureUser; |
| 32 params->is_post = false; |
| 33 } |
| 34 |
| 35 // A SafeBrowingBlockingPage class that does not create windows. |
| 36 class TestSafeBrowsingBlockingPage : public SafeBrowsingBlockingPage { |
| 37 public: |
| 38 TestSafeBrowsingBlockingPage(SafeBrowsingService* service, |
| 39 WebContents* web_contents, |
| 40 const UnsafeResourceList& unsafe_resources) |
| 41 : SafeBrowsingBlockingPage(service, web_contents, unsafe_resources) { |
| 42 } |
| 43 |
| 44 // Overriden from InterstitialPage. Don't create a view. |
| 45 virtual WebContentsView* CreateWebContentsView() { |
| 46 return NULL; |
| 47 } |
| 48 }; |
| 49 |
| 50 class TestSafeBrowsingBlockingPageFactory |
| 51 : public SafeBrowsingBlockingPageFactory { |
| 52 public: |
| 53 TestSafeBrowsingBlockingPageFactory() { } |
| 54 ~TestSafeBrowsingBlockingPageFactory() { } |
| 55 |
| 56 virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage( |
| 57 SafeBrowsingService* service, |
| 58 WebContents* web_contents, |
| 59 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources) { |
| 60 return new TestSafeBrowsingBlockingPage(service, web_contents, |
| 61 unsafe_resources); |
| 62 } |
| 63 }; |
| 64 |
| 65 class SafeBrowsingBlockingPageTest : public RenderViewHostTestHarness, |
| 66 public SafeBrowsingService::Client { |
| 67 public: |
| 68 // The decision the user made. |
| 69 enum UserResponse { |
| 70 PENDING, |
| 71 OK, |
| 72 CANCEL |
| 73 }; |
| 74 |
| 75 SafeBrowsingBlockingPageTest() { |
| 76 ResetUserResponse(); |
| 77 service_ = new SafeBrowsingService(); |
| 78 } |
| 79 |
| 80 virtual void SetUp() { |
| 81 RenderViewHostTestHarness::SetUp(); |
| 82 SafeBrowsingBlockingPage::RegisterFactory(&factory_); |
| 83 ResetUserResponse(); |
| 84 } |
| 85 |
| 86 // SafeBrowsingService::Client implementation. |
| 87 virtual void OnUrlCheckResult(const GURL& url, |
| 88 SafeBrowsingService::UrlCheckResult result) { |
| 89 } |
| 90 virtual void OnBlockingPageComplete(bool proceed) { |
| 91 if (proceed) |
| 92 user_response_ = OK; |
| 93 else |
| 94 user_response_ = CANCEL; |
| 95 } |
| 96 |
| 97 void Navigate(const char* url, int page_id) { |
| 98 ViewHostMsg_FrameNavigate_Params params; |
| 99 InitNavigateParams(¶ms, page_id, GURL(url)); |
| 100 contents()->TestDidNavigate(contents_->render_view_host(), params); |
| 101 } |
| 102 |
| 103 void ShowInterstitial(ResourceType::Type resource_type, |
| 104 const char* url) { |
| 105 SafeBrowsingService::UnsafeResource resource; |
| 106 InitResource(&resource, resource_type, GURL(url)); |
| 107 SafeBrowsingBlockingPage::ShowBlockingPage(service_, resource); |
| 108 } |
| 109 |
| 110 // Returns the SafeBrowsingBlockingPage currently showing or NULL if none is |
| 111 // showing. |
| 112 SafeBrowsingBlockingPage* GetSafeBrowsingBlockingPage() { |
| 113 InterstitialPage* interstitial = |
| 114 InterstitialPage::GetInterstitialPage(contents_); |
| 115 if (!interstitial) |
| 116 return NULL; |
| 117 return static_cast<SafeBrowsingBlockingPage*>(interstitial); |
| 118 } |
| 119 |
| 120 UserResponse user_response() const { return user_response_; } |
| 121 void ResetUserResponse() { user_response_ = PENDING; } |
| 122 |
| 123 static void ProceedThroughInterstitial( |
| 124 SafeBrowsingBlockingPage* sb_interstitial) { |
| 125 sb_interstitial->Proceed(); |
| 126 // Proceed() posts a task to update the SafeBrowsingService::Client. |
| 127 MessageLoop::current()->RunAllPending(); |
| 128 } |
| 129 |
| 130 static void DontProceedThroughInterstitial( |
| 131 SafeBrowsingBlockingPage* sb_interstitial) { |
| 132 sb_interstitial->DontProceed(); |
| 133 // DontProceed() posts a task to update the SafeBrowsingService::Client. |
| 134 MessageLoop::current()->RunAllPending(); |
| 135 } |
| 136 |
| 137 private: |
| 138 void InitResource(SafeBrowsingService::UnsafeResource* resource, |
| 139 ResourceType::Type resource_type, |
| 140 const GURL& url) { |
| 141 resource->client = this; |
| 142 resource->url = url; |
| 143 resource->resource_type = resource_type; |
| 144 resource->threat_type = SafeBrowsingService::URL_MALWARE; |
| 145 resource->render_process_host_id = contents_->process()->pid(); |
| 146 resource->render_view_id = contents_->render_view_host()->routing_id(); |
| 147 } |
| 148 |
| 149 UserResponse user_response_; |
| 150 scoped_refptr<SafeBrowsingService> service_; |
| 151 TestSafeBrowsingBlockingPageFactory factory_; |
| 152 }; |
| 153 |
| 154 // Tests showing a blocking page for a malware page and not proceeding. |
| 155 TEST_F(SafeBrowsingBlockingPageTest, MalwarePageDontProceed) { |
| 156 // Start a load. |
| 157 controller()->LoadURL(GURL(kBadURL), GURL(), PageTransition::TYPED); |
| 158 |
| 159 // Simulate the load causing a safe browsing interstitial to be shown. |
| 160 ShowInterstitial(ResourceType::MAIN_FRAME, kBadURL); |
| 161 SafeBrowsingBlockingPage* sb_interstitial = GetSafeBrowsingBlockingPage(); |
| 162 ASSERT_TRUE(sb_interstitial); |
| 163 |
| 164 // Simulate the user clicking "don't proceed". |
| 165 DontProceedThroughInterstitial(sb_interstitial); |
| 166 |
| 167 // The interstitial should be gone. |
| 168 EXPECT_EQ(CANCEL, user_response()); |
| 169 EXPECT_FALSE(GetSafeBrowsingBlockingPage()); |
| 170 |
| 171 // We did not proceed, the pending entry should be gone. |
| 172 EXPECT_FALSE(controller()->GetPendingEntry()); |
| 173 } |
| 174 |
| 175 // Tests showing a blocking page for a malware page and then proceeding. |
| 176 TEST_F(SafeBrowsingBlockingPageTest, MalwarePageProceed) { |
| 177 // Start a load. |
| 178 controller()->LoadURL(GURL(kBadURL), GURL(), PageTransition::TYPED); |
| 179 |
| 180 // Simulate the load causing a safe browsing interstitial to be shown. |
| 181 ShowInterstitial(ResourceType::MAIN_FRAME, kBadURL); |
| 182 SafeBrowsingBlockingPage* sb_interstitial = GetSafeBrowsingBlockingPage(); |
| 183 ASSERT_TRUE(sb_interstitial); |
| 184 |
| 185 // Simulate the user clicking "proceed". |
| 186 ProceedThroughInterstitial(sb_interstitial); |
| 187 |
| 188 // The interstitial is shown until the navigation commits. |
| 189 ASSERT_TRUE(InterstitialPage::GetInterstitialPage(contents_)); |
| 190 // Commit the navigation. |
| 191 Navigate(kBadURL, 1); |
| 192 // The interstitial should be gone now. |
| 193 ASSERT_FALSE(InterstitialPage::GetInterstitialPage(contents_)); |
| 194 } |
| 195 |
| 196 // Tests showing a blocking page for a page that contains malware subresources |
| 197 // and not proceeding. |
| 198 TEST_F(SafeBrowsingBlockingPageTest, PageWithMalwareResourceDontProceed) { |
| 199 // Navigate somewhere. |
| 200 Navigate(kGoogleURL, 1); |
| 201 |
| 202 // Navigate somewhere else. |
| 203 Navigate(kGoodURL, 2); |
| 204 |
| 205 // Simulate that page loading a bad-resource triggering an interstitial. |
| 206 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL); |
| 207 |
| 208 SafeBrowsingBlockingPage* sb_interstitial = GetSafeBrowsingBlockingPage(); |
| 209 ASSERT_TRUE(sb_interstitial); |
| 210 |
| 211 // Simulate the user clicking "don't proceed". |
| 212 DontProceedThroughInterstitial(sb_interstitial); |
| 213 EXPECT_EQ(CANCEL, user_response()); |
| 214 EXPECT_FALSE(GetSafeBrowsingBlockingPage()); |
| 215 |
| 216 // We did not proceed, we should be back to the first page, the 2nd one should |
| 217 // have been removed from the navigation controller. |
| 218 ASSERT_EQ(1, controller()->GetEntryCount()); |
| 219 EXPECT_EQ(kGoogleURL, controller()->GetActiveEntry()->url().spec()); |
| 220 } |
| 221 |
| 222 // Tests showing a blocking page for a page that contains malware subresources |
| 223 // and proceeding. |
| 224 TEST_F(SafeBrowsingBlockingPageTest, PageWithMalwareResourceProceed) { |
| 225 // Navigate somewhere. |
| 226 Navigate(kGoodURL, 1); |
| 227 |
| 228 // Simulate that page loading a bad-resource triggering an interstitial. |
| 229 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL); |
| 230 |
| 231 SafeBrowsingBlockingPage* sb_interstitial = GetSafeBrowsingBlockingPage(); |
| 232 ASSERT_TRUE(sb_interstitial); |
| 233 |
| 234 // Simulate the user clicking "proceed". |
| 235 ProceedThroughInterstitial(sb_interstitial); |
| 236 EXPECT_EQ(OK, user_response()); |
| 237 EXPECT_FALSE(GetSafeBrowsingBlockingPage()); |
| 238 |
| 239 // We did proceed, we should be back to showing the page. |
| 240 ASSERT_EQ(1, controller()->GetEntryCount()); |
| 241 EXPECT_EQ(kGoodURL, controller()->GetActiveEntry()->url().spec()); |
| 242 } |
| 243 |
| 244 // Tests showing a blocking page for a page that contains multiple malware |
| 245 // subresources and not proceeding. This just tests that the extra malware |
| 246 // subresources (which trigger queued interstitial pages) do not break anything. |
| 247 TEST_F(SafeBrowsingBlockingPageTest, |
| 248 PageWithMultipleMalwareResourceDontProceed) { |
| 249 // Navigate somewhere. |
| 250 Navigate(kGoogleURL, 1); |
| 251 |
| 252 // Navigate somewhere else. |
| 253 Navigate(kGoodURL, 2); |
| 254 |
| 255 // Simulate that page loading a bad-resource triggering an interstitial. |
| 256 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL); |
| 257 |
| 258 // More bad resources loading causing more interstitials. The new |
| 259 // interstitials should be queued. |
| 260 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL2); |
| 261 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL3); |
| 262 |
| 263 SafeBrowsingBlockingPage* sb_interstitial = GetSafeBrowsingBlockingPage(); |
| 264 ASSERT_TRUE(sb_interstitial); |
| 265 |
| 266 // Simulate the user clicking "don't proceed". |
| 267 DontProceedThroughInterstitial(sb_interstitial); |
| 268 EXPECT_EQ(CANCEL, user_response()); |
| 269 EXPECT_FALSE(GetSafeBrowsingBlockingPage()); |
| 270 |
| 271 // We did not proceed, we should be back to the first page, the 2nd one should |
| 272 // have been removed from the navigation controller. |
| 273 ASSERT_EQ(1, controller()->GetEntryCount()); |
| 274 EXPECT_EQ(kGoogleURL, controller()->GetActiveEntry()->url().spec()); |
| 275 } |
| 276 |
| 277 // Tests showing a blocking page for a page that contains multiple malware |
| 278 // subresources and proceeding through the first interstitial, but not the next. |
| 279 TEST_F(SafeBrowsingBlockingPageTest, |
| 280 PageWithMultipleMalwareResourceProceedThenDontProceed) { |
| 281 // Navigate somewhere. |
| 282 Navigate(kGoogleURL, 1); |
| 283 |
| 284 // Navigate somewhere else. |
| 285 Navigate(kGoodURL, 2); |
| 286 |
| 287 // Simulate that page loading a bad-resource triggering an interstitial. |
| 288 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL); |
| 289 |
| 290 // More bad resources loading causing more interstitials. The new |
| 291 // interstitials should be queued. |
| 292 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL2); |
| 293 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL3); |
| 294 |
| 295 SafeBrowsingBlockingPage* sb_interstitial = GetSafeBrowsingBlockingPage(); |
| 296 ASSERT_TRUE(sb_interstitial); |
| 297 |
| 298 // Proceed through the 1st interstitial. |
| 299 ProceedThroughInterstitial(sb_interstitial); |
| 300 EXPECT_EQ(OK, user_response()); |
| 301 |
| 302 ResetUserResponse(); |
| 303 |
| 304 // We should land to a 2nd interstitial (aggregating all the malware resources |
| 305 // loaded while the 1st interstitial was showing). |
| 306 sb_interstitial = GetSafeBrowsingBlockingPage(); |
| 307 ASSERT_TRUE(sb_interstitial); |
| 308 |
| 309 // Don't proceed through the 2nd interstitial. |
| 310 DontProceedThroughInterstitial(sb_interstitial); |
| 311 EXPECT_EQ(CANCEL, user_response()); |
| 312 EXPECT_FALSE(GetSafeBrowsingBlockingPage()); |
| 313 |
| 314 // We did not proceed, we should be back to the first page, the 2nd one should |
| 315 // have been removed from the navigation controller. |
| 316 ASSERT_EQ(1, controller()->GetEntryCount()); |
| 317 EXPECT_EQ(kGoogleURL, controller()->GetActiveEntry()->url().spec()); |
| 318 } |
| 319 |
| 320 // Tests showing a blocking page for a page that contains multiple malware |
| 321 // subresources and proceeding through the multiple interstitials. |
| 322 TEST_F(SafeBrowsingBlockingPageTest, PageWithMultipleMalwareResourceProceed) { |
| 323 // Navigate somewhere else. |
| 324 Navigate(kGoodURL, 1); |
| 325 |
| 326 // Simulate that page loading a bad-resource triggering an interstitial. |
| 327 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL); |
| 328 |
| 329 // More bad resources loading causing more interstitials. The new |
| 330 // interstitials should be queued. |
| 331 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL2); |
| 332 ShowInterstitial(ResourceType::SUB_RESOURCE, kBadURL3); |
| 333 |
| 334 SafeBrowsingBlockingPage* sb_interstitial = GetSafeBrowsingBlockingPage(); |
| 335 ASSERT_TRUE(sb_interstitial); |
| 336 |
| 337 // Proceed through the 1st interstitial. |
| 338 ProceedThroughInterstitial(sb_interstitial); |
| 339 EXPECT_EQ(OK, user_response()); |
| 340 |
| 341 ResetUserResponse(); |
| 342 |
| 343 // We should land to a 2nd interstitial (aggregating all the malware resources |
| 344 // loaded while the 1st interstitial was showing). |
| 345 sb_interstitial = GetSafeBrowsingBlockingPage(); |
| 346 ASSERT_TRUE(sb_interstitial); |
| 347 |
| 348 // Proceed through the 2nd interstitial. |
| 349 ProceedThroughInterstitial(sb_interstitial); |
| 350 EXPECT_EQ(OK, user_response()); |
| 351 |
| 352 // We did proceed, we should be back to the initial page. |
| 353 ASSERT_EQ(1, controller()->GetEntryCount()); |
| 354 EXPECT_EQ(kGoodURL, controller()->GetActiveEntry()->url().spec()); |
| 355 } |
| OLD | NEW |