Home | History | Annotate | Download | only in safe_browsing
      1 // Copyright (c) 2011 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 <algorithm>
      6 
      7 #include "base/strings/stringprintf.h"
      8 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 #include "url/gurl.h"
     11 
     12 namespace {
     13 
     14 bool VectorContains(const std::vector<std::string>& data,
     15                     const std::string& str) {
     16   return std::find(data.begin(), data.end(), str) != data.end();
     17 }
     18 
     19 // Tests that we generate the required host/path combinations for testing
     20 // according to the Safe Browsing spec.
     21 // See section 6.2 in
     22 // http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec.
     23 TEST(SafeBrowsingUtilTest, UrlParsing) {
     24   std::vector<std::string> hosts, paths;
     25 
     26   GURL url("http://a.b.c/1/2.html?param=1");
     27   safe_browsing_util::GenerateHostsToCheck(url, &hosts);
     28   safe_browsing_util::GeneratePathsToCheck(url, &paths);
     29   EXPECT_EQ(hosts.size(), static_cast<size_t>(2));
     30   EXPECT_EQ(paths.size(), static_cast<size_t>(4));
     31   EXPECT_EQ(hosts[0], "b.c");
     32   EXPECT_EQ(hosts[1], "a.b.c");
     33 
     34   EXPECT_TRUE(VectorContains(paths, "/1/2.html?param=1"));
     35   EXPECT_TRUE(VectorContains(paths, "/1/2.html"));
     36   EXPECT_TRUE(VectorContains(paths, "/1/"));
     37   EXPECT_TRUE(VectorContains(paths, "/"));
     38 
     39   url = GURL("http://a.b.c.d.e.f.g/1.html");
     40   safe_browsing_util::GenerateHostsToCheck(url, &hosts);
     41   safe_browsing_util::GeneratePathsToCheck(url, &paths);
     42   EXPECT_EQ(hosts.size(), static_cast<size_t>(5));
     43   EXPECT_EQ(paths.size(), static_cast<size_t>(2));
     44   EXPECT_EQ(hosts[0], "f.g");
     45   EXPECT_EQ(hosts[1], "e.f.g");
     46   EXPECT_EQ(hosts[2], "d.e.f.g");
     47   EXPECT_EQ(hosts[3], "c.d.e.f.g");
     48   EXPECT_EQ(hosts[4], "a.b.c.d.e.f.g");
     49   EXPECT_TRUE(VectorContains(paths, "/1.html"));
     50   EXPECT_TRUE(VectorContains(paths, "/"));
     51 
     52   url = GURL("http://a.b/saw-cgi/eBayISAPI.dll/");
     53   safe_browsing_util::GeneratePathsToCheck(url, &paths);
     54   EXPECT_EQ(paths.size(), static_cast<size_t>(3));
     55   EXPECT_TRUE(VectorContains(paths, "/saw-cgi/eBayISAPI.dll/"));
     56   EXPECT_TRUE(VectorContains(paths, "/saw-cgi/"));
     57   EXPECT_TRUE(VectorContains(paths, "/"));
     58 }
     59 
     60 // Tests the url canonicalization according to the Safe Browsing spec.
     61 // See section 6.1 in
     62 // http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec.
     63 TEST(SafeBrowsingUtilTest, CanonicalizeUrl) {
     64   struct {
     65     const char* input_url;
     66     const char* expected_canonicalized_hostname;
     67     const char* expected_canonicalized_path;
     68     const char* expected_canonicalized_query;
     69   } tests[] = {
     70     {
     71       "http://host/%25%32%35",
     72       "host",
     73       "/%25",
     74       ""
     75     }, {
     76       "http://host/%25%32%35%25%32%35",
     77       "host",
     78       "/%25%25",
     79       ""
     80     }, {
     81       "http://host/%2525252525252525",
     82       "host",
     83       "/%25",
     84       ""
     85     }, {
     86       "http://host/asdf%25%32%35asd",
     87       "host",
     88       "/asdf%25asd",
     89       ""
     90     }, {
     91       "http://host/%%%25%32%35asd%%",
     92       "host",
     93       "/%25%25%25asd%25%25",
     94       ""
     95     }, {
     96       "http://host/%%%25%32%35asd%%",
     97       "host",
     98       "/%25%25%25asd%25%25",
     99       ""
    100     }, {
    101       "http://www.google.com/",
    102       "www.google.com",
    103       "/",
    104       ""
    105     }, {
    106       "http://%31%36%38%2e%31%38%38%2e%39%39%2e%32%36/%2E%73%65%63%75%72%65/%77"
    107           "%77%77%2E%65%62%61%79%2E%63%6F%6D/",
    108       "168.188.99.26",
    109       "/.secure/www.ebay.com/",
    110       ""
    111     }, {
    112       "http://195.127.0.11/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserd"
    113           "ataxplimnbqmn-xplmvalidateinfoswqpcmlx=hgplmcx/",
    114       "195.127.0.11",
    115       "/uploads/%20%20%20%20/.verify/.eBaysecure=updateuserdataxplimnbqmn-xplmv"
    116           "alidateinfoswqpcmlx=hgplmcx/",
    117       ""
    118     }, {
    119       "http://host.com/%257Ea%2521b%2540c%2523d%2524e%25f%255E00%252611%252A"
    120           "22%252833%252944_55%252B",
    121       "host.com",
    122       "/~a!b@c%23d$e%25f^00&11*22(33)44_55+",
    123       ""
    124     }, {
    125       "http://3279880203/blah",
    126       "195.127.0.11",
    127       "/blah",
    128       ""
    129     }, {
    130       "http://www.google.com/blah/..",
    131       "www.google.com",
    132       "/",
    133       ""
    134     }, {
    135       "http://www.google.com/blah#fraq",
    136       "www.google.com",
    137       "/blah",
    138       ""
    139     }, {
    140       "http://www.GOOgle.com/",
    141       "www.google.com",
    142       "/",
    143       ""
    144     }, {
    145       "http://www.google.com.../",
    146       "www.google.com",
    147       "/",
    148       ""
    149     }, {
    150       "http://www.google.com/q?",
    151       "www.google.com",
    152       "/q",
    153       ""
    154     }, {
    155       "http://www.google.com/q?r?",
    156       "www.google.com",
    157       "/q",
    158       "r?"
    159     }, {
    160       "http://www.google.com/q?r?s",
    161       "www.google.com",
    162       "/q",
    163       "r?s"
    164     }, {
    165       "http://evil.com/foo#bar#baz",
    166       "evil.com",
    167       "/foo",
    168       ""
    169     }, {
    170       "http://evil.com/foo;",
    171       "evil.com",
    172       "/foo;",
    173       ""
    174     }, {
    175       "http://evil.com/foo?bar;",
    176       "evil.com",
    177       "/foo",
    178       "bar;"
    179     }, {
    180       "http://notrailingslash.com",
    181       "notrailingslash.com",
    182       "/",
    183       ""
    184     }, {
    185       "http://www.gotaport.com:1234/",
    186       "www.gotaport.com",
    187       "/",
    188       ""
    189     }, {
    190       "  http://www.google.com/  ",
    191       "www.google.com",
    192       "/",
    193       ""
    194     }, {
    195       "http:// leadingspace.com/",
    196       "%20leadingspace.com",
    197       "/",
    198       ""
    199     }, {
    200       "http://%20leadingspace.com/",
    201       "%20leadingspace.com",
    202       "/",
    203       ""
    204     }, {
    205       "https://www.securesite.com/",
    206       "www.securesite.com",
    207       "/",
    208       ""
    209     }, {
    210       "http://host.com/ab%23cd",
    211       "host.com",
    212       "/ab%23cd",
    213       ""
    214     }, {
    215       "http://host%3e.com//twoslashes?more//slashes",
    216       "host>.com",
    217       "/twoslashes",
    218       "more//slashes"
    219     }, {
    220       "http://host.com/abc?val=xyz#anything",
    221       "host.com",
    222       "/abc",
    223       "val=xyz"
    224     }, {
    225       "http://abc:def@host.com/xyz",
    226       "host.com",
    227       "/xyz",
    228       ""
    229     }, {
    230       "http://host%3e.com/abc/%2e%2e%2fdef",
    231       "host>.com",
    232       "/def",
    233       ""
    234     }, {
    235       "http://.......host...com.....//abc/////def%2F%2F%2Fxyz",
    236       "host.com",
    237       "/abc/def/xyz",
    238       ""
    239     }, {
    240       "ftp://host.com/foo?bar",
    241       "host.com",
    242       "/foo",
    243       "bar"
    244     }, {
    245       "data:text/html;charset=utf-8,%0D%0A",
    246       "",
    247       "",
    248       ""
    249     }, {
    250       "javascript:alert()",
    251       "",
    252       "",
    253       ""
    254     }, {
    255       "mailto:abc (at) example.com",
    256       "",
    257       "",
    258       ""
    259     },
    260   };
    261   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
    262     SCOPED_TRACE(base::StringPrintf("Test: %s", tests[i].input_url));
    263     GURL url(tests[i].input_url);
    264 
    265     std::string canonicalized_hostname;
    266     std::string canonicalized_path;
    267     std::string canonicalized_query;
    268     safe_browsing_util::CanonicalizeUrl(url, &canonicalized_hostname,
    269         &canonicalized_path, &canonicalized_query);
    270 
    271     EXPECT_EQ(tests[i].expected_canonicalized_hostname,
    272               canonicalized_hostname);
    273     EXPECT_EQ(tests[i].expected_canonicalized_path,
    274               canonicalized_path);
    275     EXPECT_EQ(tests[i].expected_canonicalized_query,
    276               canonicalized_query);
    277   }
    278 }
    279 
    280 TEST(SafeBrowsingUtilTest, ListIdListNameConversion) {
    281   std::string list_name;
    282   EXPECT_FALSE(safe_browsing_util::GetListName(safe_browsing_util::INVALID,
    283                                                &list_name));
    284   EXPECT_TRUE(safe_browsing_util::GetListName(safe_browsing_util::MALWARE,
    285                                               &list_name));
    286   EXPECT_EQ(list_name, std::string(safe_browsing_util::kMalwareList));
    287   EXPECT_EQ(safe_browsing_util::MALWARE,
    288             safe_browsing_util::GetListId(list_name));
    289 
    290   EXPECT_TRUE(safe_browsing_util::GetListName(safe_browsing_util::PHISH,
    291                                               &list_name));
    292   EXPECT_EQ(list_name, std::string(safe_browsing_util::kPhishingList));
    293   EXPECT_EQ(safe_browsing_util::PHISH,
    294             safe_browsing_util::GetListId(list_name));
    295 
    296   EXPECT_TRUE(safe_browsing_util::GetListName(safe_browsing_util::BINURL,
    297                                               &list_name));
    298   EXPECT_EQ(list_name, std::string(safe_browsing_util::kBinUrlList));
    299   EXPECT_EQ(safe_browsing_util::BINURL,
    300             safe_browsing_util::GetListId(list_name));
    301 }
    302 
    303 // Since the ids are saved in file, we need to make sure they don't change.
    304 // Since only the last bit of each id is saved in file together with
    305 // chunkids, this checks only last bit.
    306 TEST(SafeBrowsingUtilTest, ListIdVerification) {
    307   EXPECT_EQ(0, safe_browsing_util::MALWARE % 2);
    308   EXPECT_EQ(1, safe_browsing_util::PHISH % 2);
    309   EXPECT_EQ(0, safe_browsing_util::BINURL %2);
    310 }
    311 
    312 TEST(SafeBrowsingUtilTest, StringToSBFullHashAndSBFullHashToString) {
    313   // 31 chars plus the last \0 as full_hash.
    314   const std::string hash_in = "12345678902234567890323456789012";
    315   SBFullHash hash_out = safe_browsing_util::StringToSBFullHash(hash_in);
    316   EXPECT_EQ(0x34333231U, hash_out.prefix);
    317   EXPECT_EQ(0, memcmp(hash_in.data(), hash_out.full_hash, sizeof(SBFullHash)));
    318 
    319   std::string hash_final = safe_browsing_util::SBFullHashToString(hash_out);
    320   EXPECT_EQ(hash_in, hash_final);
    321 }
    322 
    323 TEST(SafeBrowsingUtilTest, FullHashOperators) {
    324   const SBFullHash kHash1 = SBFullHashForString("one");
    325   const SBFullHash kHash2 = SBFullHashForString("two");
    326 
    327   EXPECT_TRUE(SBFullHashEqual(kHash1, kHash1));
    328   EXPECT_TRUE(SBFullHashEqual(kHash2, kHash2));
    329   EXPECT_FALSE(SBFullHashEqual(kHash1, kHash2));
    330   EXPECT_FALSE(SBFullHashEqual(kHash2, kHash1));
    331 
    332   EXPECT_FALSE(SBFullHashLess(kHash1, kHash2));
    333   EXPECT_TRUE(SBFullHashLess(kHash2, kHash1));
    334 
    335   EXPECT_FALSE(SBFullHashLess(kHash1, kHash1));
    336   EXPECT_FALSE(SBFullHashLess(kHash2, kHash2));
    337 }
    338 
    339 }  // namespace
    340