OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 // Unit tests for the SafeBrowsing storage system. | 5 // Unit tests for the SafeBrowsing storage system. |
6 | 6 |
7 #include "chrome/browser/safe_browsing/safe_browsing_database.h" | 7 #include "chrome/browser/safe_browsing/safe_browsing_database.h" |
8 | 8 |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
13 #include "base/files/scoped_temp_dir.h" | 13 #include "base/files/scoped_temp_dir.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
16 #include "base/sha1.h" | 16 #include "base/sha1.h" |
17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/string_split.h" | 18 #include "base/strings/string_split.h" |
19 #include "base/test/test_simple_task_runner.h" | 19 #include "base/test/test_simple_task_runner.h" |
20 #include "base/time/time.h" | 20 #include "base/time/time.h" |
21 #include "chrome/browser/safe_browsing/chunk.pb.h" | 21 #include "chrome/browser/safe_browsing/chunk.pb.h" |
22 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h" | 22 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h" |
23 #include "crypto/sha2.h" | 23 #include "crypto/sha2.h" |
24 #include "net/base/ip_address_number.h" | 24 #include "net/base/ip_address_number.h" |
| 25 #include "testing/gmock/include/gmock/gmock.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
26 #include "testing/platform_test.h" | 27 #include "testing/platform_test.h" |
27 #include "url/gurl.h" | 28 #include "url/gurl.h" |
28 | 29 |
29 using base::Time; | 30 using base::Time; |
30 using base::TimeDelta; | 31 using base::TimeDelta; |
31 | 32 |
32 namespace safe_browsing { | 33 namespace safe_browsing { |
33 | 34 |
34 namespace { | 35 namespace { |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 SafeBrowsingStoreFile* inclusion_whitelist_store = | 276 SafeBrowsingStoreFile* inclusion_whitelist_store = |
276 new SafeBrowsingStoreFile(task_runner_); | 277 new SafeBrowsingStoreFile(task_runner_); |
277 SafeBrowsingStoreFile* extension_blacklist_store = | 278 SafeBrowsingStoreFile* extension_blacklist_store = |
278 new SafeBrowsingStoreFile(task_runner_); | 279 new SafeBrowsingStoreFile(task_runner_); |
279 SafeBrowsingStoreFile* ip_blacklist_store = | 280 SafeBrowsingStoreFile* ip_blacklist_store = |
280 new SafeBrowsingStoreFile(task_runner_); | 281 new SafeBrowsingStoreFile(task_runner_); |
281 SafeBrowsingStoreFile* unwanted_software_store = | 282 SafeBrowsingStoreFile* unwanted_software_store = |
282 new SafeBrowsingStoreFile(task_runner_); | 283 new SafeBrowsingStoreFile(task_runner_); |
283 SafeBrowsingStoreFile* module_whitelist_store = | 284 SafeBrowsingStoreFile* module_whitelist_store = |
284 new SafeBrowsingStoreFile(task_runner_); | 285 new SafeBrowsingStoreFile(task_runner_); |
| 286 SafeBrowsingStoreFile* resource_blacklist_store = |
| 287 new SafeBrowsingStoreFile(task_runner_); |
285 database_.reset(new SafeBrowsingDatabaseNew( | 288 database_.reset(new SafeBrowsingDatabaseNew( |
286 task_runner_, browse_store, download_store, csd_whitelist_store, | 289 task_runner_, browse_store, download_store, csd_whitelist_store, |
287 download_whitelist_store, inclusion_whitelist_store, | 290 download_whitelist_store, inclusion_whitelist_store, |
288 extension_blacklist_store, ip_blacklist_store, unwanted_software_store, | 291 extension_blacklist_store, ip_blacklist_store, unwanted_software_store, |
289 module_whitelist_store)); | 292 module_whitelist_store, resource_blacklist_store)); |
290 database_->Init(database_filename_); | 293 database_->Init(database_filename_); |
291 } | 294 } |
292 | 295 |
293 bool ContainsDownloadUrl(const std::vector<GURL>& urls, | 296 bool ContainsDownloadUrl(const std::vector<GURL>& urls, |
294 std::vector<SBPrefix>* prefix_hits) { | 297 std::vector<SBPrefix>* prefix_hits) { |
295 std::vector<SBPrefix> prefixes; | 298 std::vector<SBPrefix> prefixes; |
296 SafeBrowsingDatabase::GetDownloadUrlPrefixes(urls, &prefixes); | 299 SafeBrowsingDatabase::GetDownloadUrlPrefixes(urls, &prefixes); |
297 return database_->ContainsDownloadUrlPrefixes(prefixes, prefix_hits); | 300 return database_->ContainsDownloadUrlPrefixes(prefixes, prefix_hits); |
298 } | 301 } |
299 | 302 |
| 303 bool ContainsResourceUrl(const GURL& url, |
| 304 std::vector<SBPrefix>* prefix_hits) { |
| 305 std::vector<SBFullHash> full_hashes; |
| 306 UrlToFullHashes(url, false, &full_hashes); |
| 307 std::vector<SBPrefix> prefixes(full_hashes.size()); |
| 308 for (size_t i = 0; i < full_hashes.size(); ++i) |
| 309 prefixes[i] = full_hashes[i].prefix; |
| 310 return database_->ContainsResourceUrlPrefixes(prefixes, prefix_hits); |
| 311 } |
| 312 |
300 void GetListsInfo(std::vector<SBListChunkRanges>* lists) { | 313 void GetListsInfo(std::vector<SBListChunkRanges>* lists) { |
301 lists->clear(); | 314 lists->clear(); |
302 ASSERT_TRUE(database_->UpdateStarted(lists)); | 315 ASSERT_TRUE(database_->UpdateStarted(lists)); |
303 database_->UpdateFinished(true); | 316 database_->UpdateFinished(true); |
304 } | 317 } |
305 | 318 |
306 // Helper function to do an AddDel or SubDel command. | 319 // Helper function to do an AddDel or SubDel command. |
307 void DelChunk(const std::string& list, | 320 void DelChunk(const std::string& list, |
308 int chunk_id, | 321 int chunk_id, |
309 bool is_sub_del) { | 322 bool is_sub_del) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 database_->InsertChunks(kIPBlacklist, chunks); | 452 database_->InsertChunks(kIPBlacklist, chunks); |
440 | 453 |
441 chunks.clear(); | 454 chunks.clear(); |
442 chunks.push_back(AddChunkPrefixValue(11, "www.unwanted.com/software.html")); | 455 chunks.push_back(AddChunkPrefixValue(11, "www.unwanted.com/software.html")); |
443 database_->InsertChunks(kUnwantedUrlList, chunks); | 456 database_->InsertChunks(kUnwantedUrlList, chunks); |
444 | 457 |
445 chunks.clear(); | 458 chunks.clear(); |
446 chunks.push_back(AddChunkPrefixValue(12, "chrome.dll")); | 459 chunks.push_back(AddChunkPrefixValue(12, "chrome.dll")); |
447 database_->InsertChunks(kModuleWhitelist, chunks); | 460 database_->InsertChunks(kModuleWhitelist, chunks); |
448 | 461 |
| 462 chunks.clear(); |
| 463 chunks.push_back(AddChunkPrefixValue(13, "foo.com/script.js")); |
| 464 database_->InsertChunks(kResourceBlacklist, chunks); |
| 465 |
449 database_->UpdateFinished(true); | 466 database_->UpdateFinished(true); |
450 | 467 |
451 GetListsInfo(&lists); | 468 GetListsInfo(&lists); |
452 ASSERT_EQ(10U, lists.size()); | 469 ASSERT_EQ(11U, lists.size()); |
453 EXPECT_EQ(kMalwareList, lists[0].name); | 470 EXPECT_EQ(kMalwareList, lists[0].name); |
454 EXPECT_EQ("1", lists[0].adds); | 471 EXPECT_EQ("1", lists[0].adds); |
455 EXPECT_TRUE(lists[0].subs.empty()); | 472 EXPECT_TRUE(lists[0].subs.empty()); |
456 EXPECT_EQ(kPhishingList, lists[1].name); | 473 EXPECT_EQ(kPhishingList, lists[1].name); |
457 EXPECT_EQ("2", lists[1].adds); | 474 EXPECT_EQ("2", lists[1].adds); |
458 EXPECT_TRUE(lists[1].subs.empty()); | 475 EXPECT_TRUE(lists[1].subs.empty()); |
459 EXPECT_EQ(kBinUrlList, lists[2].name); | 476 EXPECT_EQ(kBinUrlList, lists[2].name); |
460 EXPECT_EQ("3", lists[2].adds); | 477 EXPECT_EQ("3", lists[2].adds); |
461 EXPECT_TRUE(lists[2].subs.empty()); | 478 EXPECT_TRUE(lists[2].subs.empty()); |
462 EXPECT_EQ(kCsdWhiteList, lists[3].name); | 479 EXPECT_EQ(kCsdWhiteList, lists[3].name); |
(...skipping 10 matching lines...) Expand all Loading... |
473 EXPECT_TRUE(lists[6].subs.empty()); | 490 EXPECT_TRUE(lists[6].subs.empty()); |
474 EXPECT_EQ(kIPBlacklist, lists[7].name); | 491 EXPECT_EQ(kIPBlacklist, lists[7].name); |
475 EXPECT_EQ("10", lists[7].adds); | 492 EXPECT_EQ("10", lists[7].adds); |
476 EXPECT_TRUE(lists[7].subs.empty()); | 493 EXPECT_TRUE(lists[7].subs.empty()); |
477 EXPECT_EQ(kUnwantedUrlList, lists[8].name); | 494 EXPECT_EQ(kUnwantedUrlList, lists[8].name); |
478 EXPECT_EQ("11", lists[8].adds); | 495 EXPECT_EQ("11", lists[8].adds); |
479 EXPECT_TRUE(lists[8].subs.empty()); | 496 EXPECT_TRUE(lists[8].subs.empty()); |
480 EXPECT_EQ(kModuleWhitelist, lists[9].name); | 497 EXPECT_EQ(kModuleWhitelist, lists[9].name); |
481 EXPECT_EQ("12", lists[9].adds); | 498 EXPECT_EQ("12", lists[9].adds); |
482 EXPECT_TRUE(lists[9].subs.empty()); | 499 EXPECT_TRUE(lists[9].subs.empty()); |
| 500 EXPECT_EQ(kResourceBlacklist, lists[10].name); |
| 501 EXPECT_EQ("13", lists[10].adds); |
| 502 EXPECT_TRUE(lists[10].subs.empty()); |
483 | 503 |
484 database_.reset(); | 504 database_.reset(); |
485 } | 505 } |
486 | 506 |
487 // Checks database reading and writing for browse and unwanted PrefixSets. | 507 // Checks database reading and writing for browse and unwanted PrefixSets. |
488 TEST_F(SafeBrowsingDatabaseTest, BrowseAndUnwantedDatabasesAndPrefixSets) { | 508 TEST_F(SafeBrowsingDatabaseTest, BrowseAndUnwantedDatabasesAndPrefixSets) { |
489 | 509 |
490 struct TestCase { | 510 struct TestCase { |
491 using TestListContainsBadUrl = bool (SafeBrowsingDatabase::*)( | 511 using TestListContainsBadUrl = bool (SafeBrowsingDatabase::*)( |
492 const GURL& url, | 512 const GURL& url, |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 // TODO(shess): Disabled until ScopedLogMessageIgnorer resolved. | 1175 // TODO(shess): Disabled until ScopedLogMessageIgnorer resolved. |
1156 // http://crbug.com/56448 | 1176 // http://crbug.com/56448 |
1157 TEST_F(SafeBrowsingDatabaseTest, DISABLED_FileCorruptionHandling) { | 1177 TEST_F(SafeBrowsingDatabaseTest, DISABLED_FileCorruptionHandling) { |
1158 // Re-create the database in a captive message loop so that we can | 1178 // Re-create the database in a captive message loop so that we can |
1159 // influence task-posting. Database specifically needs to the | 1179 // influence task-posting. Database specifically needs to the |
1160 // file-backed. | 1180 // file-backed. |
1161 database_.reset(); | 1181 database_.reset(); |
1162 base::MessageLoop loop; | 1182 base::MessageLoop loop; |
1163 SafeBrowsingStoreFile* store = new SafeBrowsingStoreFile(task_runner_); | 1183 SafeBrowsingStoreFile* store = new SafeBrowsingStoreFile(task_runner_); |
1164 database_.reset(new SafeBrowsingDatabaseNew( | 1184 database_.reset(new SafeBrowsingDatabaseNew( |
1165 task_runner_, store, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); | 1185 task_runner_, store, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 1186 NULL)); |
1166 database_->Init(database_filename_); | 1187 database_->Init(database_filename_); |
1167 | 1188 |
1168 // This will cause an empty database to be created. | 1189 // This will cause an empty database to be created. |
1169 std::vector<SBListChunkRanges> lists; | 1190 std::vector<SBListChunkRanges> lists; |
1170 ASSERT_TRUE(database_->UpdateStarted(&lists)); | 1191 ASSERT_TRUE(database_->UpdateStarted(&lists)); |
1171 database_->UpdateFinished(true); | 1192 database_->UpdateFinished(true); |
1172 | 1193 |
1173 // Create a sub chunk to insert. | 1194 // Create a sub chunk to insert. |
1174 std::vector<scoped_ptr<SBChunkData>> chunks; | 1195 std::vector<scoped_ptr<SBChunkData>> chunks; |
1175 chunks.push_back(SubChunkPrefixValue(7, | 1196 chunks.push_back(SubChunkPrefixValue(7, |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1296 urls.clear(); | 1317 urls.clear(); |
1297 urls.push_back(GURL(std::string("http://") + kEvil1Url1)); | 1318 urls.push_back(GURL(std::string("http://") + kEvil1Url1)); |
1298 urls.push_back(GURL(std::string("https://") + kEvil1Url2)); | 1319 urls.push_back(GURL(std::string("https://") + kEvil1Url2)); |
1299 EXPECT_TRUE(ContainsDownloadUrl(urls, &prefix_hits)); | 1320 EXPECT_TRUE(ContainsDownloadUrl(urls, &prefix_hits)); |
1300 ASSERT_EQ(2U, prefix_hits.size()); | 1321 ASSERT_EQ(2U, prefix_hits.size()); |
1301 EXPECT_EQ(SBPrefixForString(kEvil1Url1), prefix_hits[0]); | 1322 EXPECT_EQ(SBPrefixForString(kEvil1Url1), prefix_hits[0]); |
1302 EXPECT_EQ(SBPrefixForString(kEvil1Url2), prefix_hits[1]); | 1323 EXPECT_EQ(SBPrefixForString(kEvil1Url2), prefix_hits[1]); |
1303 database_.reset(); | 1324 database_.reset(); |
1304 } | 1325 } |
1305 | 1326 |
| 1327 TEST_F(SafeBrowsingDatabaseTest, ContainsResourceUrlPrefixes) { |
| 1328 const char* kBadUrl1 = "bad1.com/"; |
| 1329 const char* kBadUrl2 = "bad2.com/script.js"; |
| 1330 const SBPrefix kBadPrefix1 = SBPrefixForString(kBadUrl1); |
| 1331 const SBPrefix kBadPrefix2 = SBPrefixForString(kBadUrl2); |
| 1332 |
| 1333 // Populate database |
| 1334 std::vector<scoped_ptr<SBChunkData>> chunks; |
| 1335 chunks.push_back(AddChunkPrefix2Value(1, kBadUrl1, kBadUrl2)); |
| 1336 |
| 1337 std::vector<SBListChunkRanges> lists; |
| 1338 ASSERT_TRUE(database_->UpdateStarted(&lists)); |
| 1339 database_->InsertChunks(kResourceBlacklist, chunks); |
| 1340 database_->UpdateFinished(true); |
| 1341 |
| 1342 struct { |
| 1343 std::string url; |
| 1344 bool found_in_db; |
| 1345 std::vector<SBPrefix> prefix_hits; |
| 1346 } test_cases[] = { |
| 1347 {std::string("http://") + kBadUrl1, true, {kBadPrefix1}}, |
| 1348 {std::string("https://") + kBadUrl2, true, {kBadPrefix2}}, |
| 1349 {std::string("ftp://") + kBadUrl1, true, {kBadPrefix1}}, |
| 1350 {std::string("http://") + kBadUrl1 + "a/b/?arg=value", true, {kBadPrefix1}}, |
| 1351 {std::string("http://") + kBadUrl1 + "script.js", true, {kBadPrefix1}}, |
| 1352 {std::string("http://www.domain.") + kBadUrl2, true, {kBadPrefix2}}, |
| 1353 {"http://www.good.org/script.js", false, std::vector<SBPrefix>()}, |
| 1354 }; |
| 1355 |
| 1356 std::vector<SBPrefix> prefix_hits; |
| 1357 for (const auto& test_case : test_cases) { |
| 1358 EXPECT_EQ(test_case.found_in_db, |
| 1359 ContainsResourceUrl(GURL(test_case.url), &prefix_hits)); |
| 1360 EXPECT_THAT(prefix_hits, testing::ElementsAreArray(test_case.prefix_hits)); |
| 1361 } |
| 1362 |
| 1363 database_.reset(); |
| 1364 } |
| 1365 |
1306 // Checks that the whitelists are handled properly. | 1366 // Checks that the whitelists are handled properly. |
1307 TEST_F(SafeBrowsingDatabaseTest, Whitelists) { | 1367 TEST_F(SafeBrowsingDatabaseTest, Whitelists) { |
1308 struct TestCase { | 1368 struct TestCase { |
1309 using TestListContainsWhitelistedUrl = | 1369 using TestListContainsWhitelistedUrl = |
1310 bool (SafeBrowsingDatabase::*)(const GURL& url); | 1370 bool (SafeBrowsingDatabase::*)(const GURL& url); |
1311 using TestListContainsWhitelistedString = | 1371 using TestListContainsWhitelistedString = |
1312 bool (SafeBrowsingDatabase::*)(const std::string& str); | 1372 bool (SafeBrowsingDatabase::*)(const std::string& str); |
1313 | 1373 |
1314 // Returns true if urls should be tested in this test case (i.e. | 1374 // Returns true if urls should be tested in this test case (i.e. |
1315 // |test_list_contains_whitelisted_url| is not null). | 1375 // |test_list_contains_whitelisted_url| is not null). |
(...skipping 20 matching lines...) Expand all Loading... |
1336 &SafeBrowsingDatabase::ContainsDownloadWhitelistedString}, | 1396 &SafeBrowsingDatabase::ContainsDownloadWhitelistedString}, |
1337 {kInclusionWhitelist, | 1397 {kInclusionWhitelist, |
1338 &SafeBrowsingDatabase::ContainsInclusionWhitelistedUrl, nullptr}, | 1398 &SafeBrowsingDatabase::ContainsInclusionWhitelistedUrl, nullptr}, |
1339 {kModuleWhitelist, nullptr, | 1399 {kModuleWhitelist, nullptr, |
1340 &SafeBrowsingDatabase::ContainsModuleWhitelistedString}, | 1400 &SafeBrowsingDatabase::ContainsModuleWhitelistedString}, |
1341 }; | 1401 }; |
1342 | 1402 |
1343 // If the whitelist is disabled everything should match the whitelist. | 1403 // If the whitelist is disabled everything should match the whitelist. |
1344 database_.reset(new SafeBrowsingDatabaseNew( | 1404 database_.reset(new SafeBrowsingDatabaseNew( |
1345 task_runner_, new SafeBrowsingStoreFile(task_runner_), NULL, NULL, NULL, | 1405 task_runner_, new SafeBrowsingStoreFile(task_runner_), NULL, NULL, NULL, |
1346 NULL, NULL, NULL, NULL, NULL)); | 1406 NULL, NULL, NULL, NULL, NULL, NULL)); |
1347 database_->Init(database_filename_); | 1407 database_->Init(database_filename_); |
1348 for (const auto& test_case : kTestCases) { | 1408 for (const auto& test_case : kTestCases) { |
1349 SCOPED_TRACE(std::string("Tested list at fault => ") + | 1409 SCOPED_TRACE(std::string("Tested list at fault => ") + |
1350 test_case.test_list_name); | 1410 test_case.test_list_name); |
1351 | 1411 |
1352 if (test_case.TestUrls()) { | 1412 if (test_case.TestUrls()) { |
1353 EXPECT_TRUE( | 1413 EXPECT_TRUE( |
1354 (database_.get()->*test_case.test_list_contains_whitelisted_url)( | 1414 (database_.get()->*test_case.test_list_contains_whitelisted_url)( |
1355 GURL(std::string("http://www.phishing.com/")))); | 1415 GURL(std::string("http://www.phishing.com/")))); |
1356 } | 1416 } |
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2311 ASSERT_EQ(1U, prefix_hits.size()); | 2371 ASSERT_EQ(1U, prefix_hits.size()); |
2312 EXPECT_EQ(SBPrefixForString(kExampleCollision), prefix_hits[0]); | 2372 EXPECT_EQ(SBPrefixForString(kExampleCollision), prefix_hits[0]); |
2313 EXPECT_TRUE(cache_hits.empty()); | 2373 EXPECT_TRUE(cache_hits.empty()); |
2314 | 2374 |
2315 // This prefix collides, but no full hash match. | 2375 // This prefix collides, but no full hash match. |
2316 EXPECT_FALSE(database_->ContainsBrowseUrl( | 2376 EXPECT_FALSE(database_->ContainsBrowseUrl( |
2317 GURL(std::string("http://") + kExampleFine), &prefix_hits, &cache_hits)); | 2377 GURL(std::string("http://") + kExampleFine), &prefix_hits, &cache_hits)); |
2318 } | 2378 } |
2319 | 2379 |
2320 } // namespace safe_browsing | 2380 } // namespace safe_browsing |
OLD | NEW |