• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
6 #include "base/logging.h"
7 #include "base/time.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "chrome/browser/safe_browsing/protocol_manager.h"
10 
11 using base::Time;
12 using base::TimeDelta;
13 
14 static const char kInfoUrlPrefix[] = "http://info.prefix.com/foo";
15 static const char kMacKeyUrlPrefix[] = "https://key.prefix.com/bar";
16 static const char kClient[] = "unittest";
17 static const char kAppVer[] = "1.0";
18 static const char kClientKey[] = "SCg9lcLHd0dfksXgYsacwQ==";
19 static const char kWrappedKey[] =
20     "AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8nNaYH47tiQ7pDe9cEErjVHGZaPPUau5h61tbXSDqA"
21     "BiJZnDFByc_g8B5vTwxkhBf9g==";
22 static const char kAdditionalQuery[] = "additional_query";
23 
24 class SafeBrowsingProtocolManagerTest : public testing::Test {
25 };
26 
27 // Ensure that we respect section 5 of the SafeBrowsing protocol specification.
TEST_F(SafeBrowsingProtocolManagerTest,TestBackOffTimes)28 TEST_F(SafeBrowsingProtocolManagerTest, TestBackOffTimes) {
29   SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
30                                  kInfoUrlPrefix, kMacKeyUrlPrefix, false);
31   pm.next_update_sec_ = 1800;
32   DCHECK(pm.back_off_fuzz_ >= 0.0 && pm.back_off_fuzz_ <= 1.0);
33 
34   // No errors received so far.
35   EXPECT_EQ(pm.GetNextUpdateTime(false), 1800 * 1000);
36 
37   // 1 error.
38   EXPECT_EQ(pm.GetNextUpdateTime(true), 60 * 1000);
39 
40   // 2 errors.
41   int next_time = pm.GetNextUpdateTime(true) / (60 * 1000);  // Minutes
42   EXPECT_TRUE(next_time >= 30 && next_time <= 60);
43 
44   // 3 errors.
45   next_time = pm.GetNextUpdateTime(true) / (60 * 1000);
46   EXPECT_TRUE(next_time >= 60 && next_time <= 120);
47 
48   // 4 errors.
49   next_time = pm.GetNextUpdateTime(true) / (60 * 1000);
50   EXPECT_TRUE(next_time >= 120 && next_time <= 240);
51 
52   // 5 errors.
53   next_time = pm.GetNextUpdateTime(true) / (60 * 1000);
54   EXPECT_TRUE(next_time >= 240 && next_time <= 480);
55 
56   // 6 errors, reached max backoff.
57   EXPECT_EQ(pm.GetNextUpdateTime(true), 480 * 60 * 1000);
58 
59   // 7 errors.
60   EXPECT_EQ(pm.GetNextUpdateTime(true), 480 * 60 * 1000);
61 
62   // Received a successful response.
63   EXPECT_EQ(pm.GetNextUpdateTime(false), 1800 * 1000);
64 }
65 
66 // Test string combinations with and without MAC.
TEST_F(SafeBrowsingProtocolManagerTest,TestChunkStrings)67 TEST_F(SafeBrowsingProtocolManagerTest, TestChunkStrings) {
68   SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
69                                  kInfoUrlPrefix, kMacKeyUrlPrefix, false);
70 
71   // Add and Sub chunks.
72   SBListChunkRanges phish("goog-phish-shavar");
73   phish.adds = "1,4,6,8-20,99";
74   phish.subs = "16,32,64-96";
75   EXPECT_EQ(pm.FormatList(phish, false),
76             "goog-phish-shavar;a:1,4,6,8-20,99:s:16,32,64-96\n");
77   EXPECT_EQ(pm.FormatList(phish, true),
78             "goog-phish-shavar;a:1,4,6,8-20,99:s:16,32,64-96:mac\n");
79 
80   // Add chunks only.
81   phish.subs = "";
82   EXPECT_EQ(pm.FormatList(phish, false),
83             "goog-phish-shavar;a:1,4,6,8-20,99\n");
84   EXPECT_EQ(pm.FormatList(phish, true),
85             "goog-phish-shavar;a:1,4,6,8-20,99:mac\n");
86 
87   // Sub chunks only.
88   phish.adds = "";
89   phish.subs = "16,32,64-96";
90   EXPECT_EQ(pm.FormatList(phish, false), "goog-phish-shavar;s:16,32,64-96\n");
91   EXPECT_EQ(pm.FormatList(phish, true),
92             "goog-phish-shavar;s:16,32,64-96:mac\n");
93 
94   // No chunks of either type.
95   phish.adds = "";
96   phish.subs = "";
97   EXPECT_EQ(pm.FormatList(phish, false), "goog-phish-shavar;\n");
98   EXPECT_EQ(pm.FormatList(phish, true), "goog-phish-shavar;mac\n");
99 }
100 
TEST_F(SafeBrowsingProtocolManagerTest,TestGetHashBackOffTimes)101 TEST_F(SafeBrowsingProtocolManagerTest, TestGetHashBackOffTimes) {
102   SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
103                                  kInfoUrlPrefix, kMacKeyUrlPrefix, false);
104 
105   // No errors or back off time yet.
106   EXPECT_EQ(pm.gethash_error_count_, 0);
107   EXPECT_TRUE(pm.next_gethash_time_.is_null());
108 
109   Time now = Time::Now();
110 
111   // 1 error.
112   pm.HandleGetHashError(now);
113   EXPECT_EQ(pm.gethash_error_count_, 1);
114   TimeDelta margin = TimeDelta::FromSeconds(5);  // Fudge factor.
115   Time future = now + TimeDelta::FromMinutes(1);
116   EXPECT_TRUE(pm.next_gethash_time_ >= future - margin &&
117               pm.next_gethash_time_ <= future + margin);
118 
119   // 2 errors.
120   pm.HandleGetHashError(now);
121   EXPECT_EQ(pm.gethash_error_count_, 2);
122   EXPECT_TRUE(pm.next_gethash_time_ >= now + TimeDelta::FromMinutes(30));
123   EXPECT_TRUE(pm.next_gethash_time_ <= now + TimeDelta::FromMinutes(60));
124 
125   // 3 errors.
126   pm.HandleGetHashError(now);
127   EXPECT_EQ(pm.gethash_error_count_, 3);
128   EXPECT_TRUE(pm.next_gethash_time_ >= now + TimeDelta::FromMinutes(60));
129   EXPECT_TRUE(pm.next_gethash_time_ <= now + TimeDelta::FromMinutes(120));
130 
131   // 4 errors.
132   pm.HandleGetHashError(now);
133   EXPECT_EQ(pm.gethash_error_count_, 4);
134   EXPECT_TRUE(pm.next_gethash_time_ >= now + TimeDelta::FromMinutes(120));
135   EXPECT_TRUE(pm.next_gethash_time_ <= now + TimeDelta::FromMinutes(240));
136 
137   // 5 errors.
138   pm.HandleGetHashError(now);
139   EXPECT_EQ(pm.gethash_error_count_, 5);
140   EXPECT_TRUE(pm.next_gethash_time_ >= now + TimeDelta::FromMinutes(240));
141   EXPECT_TRUE(pm.next_gethash_time_ <= now + TimeDelta::FromMinutes(480));
142 
143   // 6 errors, reached max backoff.
144   pm.HandleGetHashError(now);
145   EXPECT_EQ(pm.gethash_error_count_, 6);
146   EXPECT_TRUE(pm.next_gethash_time_ == now + TimeDelta::FromMinutes(480));
147 
148   // 7 errors.
149   pm.HandleGetHashError(now);
150   EXPECT_EQ(pm.gethash_error_count_, 7);
151   EXPECT_TRUE(pm.next_gethash_time_== now + TimeDelta::FromMinutes(480));
152 }
153 
TEST_F(SafeBrowsingProtocolManagerTest,TestGetHashUrl)154 TEST_F(SafeBrowsingProtocolManagerTest, TestGetHashUrl) {
155   SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
156                                  kInfoUrlPrefix, kMacKeyUrlPrefix, false);
157   pm.version_ = kAppVer;
158   EXPECT_EQ("http://info.prefix.com/foo/gethash?client=unittest&appver=1.0&"
159             "pver=2.2", pm.GetHashUrl(false).spec());
160   EXPECT_EQ("http://info.prefix.com/foo/gethash?client=unittest&appver=1.0&"
161             "pver=2.2&wrkey=AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8nNaYH47tiQ7pDe9cE"
162             "ErjVHGZaPPUau5h61tbXSDqABiJZnDFByc_g8B5vTwxkhBf9g==",
163             pm.GetHashUrl(true).spec());
164 
165   pm.set_additional_query(kAdditionalQuery);
166   EXPECT_EQ("http://info.prefix.com/foo/gethash?client=unittest&appver=1.0&"
167             "pver=2.2&additional_query",
168             pm.GetHashUrl(false).spec());
169   EXPECT_EQ("http://info.prefix.com/foo/gethash?client=unittest&appver=1.0&"
170             "pver=2.2&additional_query&wrkey=AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8"
171             "nNaYH47tiQ7pDe9cEErjVHGZaPPUau5h61tbXSDqABiJZnDFByc_g8B5vTwxkhBf"
172             "9g==", pm.GetHashUrl(true).spec());
173 }
174 
TEST_F(SafeBrowsingProtocolManagerTest,TestUpdateUrl)175 TEST_F(SafeBrowsingProtocolManagerTest, TestUpdateUrl) {
176   SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
177                                  kInfoUrlPrefix, kMacKeyUrlPrefix, false);
178   pm.version_ = kAppVer;
179 
180   EXPECT_EQ("http://info.prefix.com/foo/downloads?client=unittest&appver=1.0&"
181             "pver=2.2", pm.UpdateUrl(false).spec());
182   EXPECT_EQ("http://info.prefix.com/foo/downloads?client=unittest&appver=1.0&"
183             "pver=2.2&wrkey=AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8nNaYH47tiQ7pDe9cE"
184             "ErjVHGZaPPUau5h61tbXSDqABiJZnDFByc_g8B5vTwxkhBf9g==",
185             pm.UpdateUrl(true).spec());
186 
187   pm.set_additional_query(kAdditionalQuery);
188   EXPECT_EQ("http://info.prefix.com/foo/downloads?client=unittest&appver=1.0&"
189             "pver=2.2&additional_query", pm.UpdateUrl(false).spec());
190   EXPECT_EQ("http://info.prefix.com/foo/downloads?client=unittest&appver=1.0&"
191             "pver=2.2&additional_query&wrkey=AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8"
192             "nNaYH47tiQ7pDe9cEErjVHGZaPPUau5h61tbXSDqABiJZnDFByc_g8B5vTwxkhBf"
193             "9g==", pm.UpdateUrl(true).spec());
194 }
195 
TEST_F(SafeBrowsingProtocolManagerTest,TestSafeBrowsingHitUrl)196 TEST_F(SafeBrowsingProtocolManagerTest, TestSafeBrowsingHitUrl) {
197   SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
198                                  kInfoUrlPrefix, kMacKeyUrlPrefix, false);
199   pm.version_ = kAppVer;
200 
201   GURL malicious_url("http://malicious.url.com");
202   GURL page_url("http://page.url.com");
203   GURL referrer_url("http://referrer.url.com");
204   EXPECT_EQ("http://info.prefix.com/foo/report?client=unittest&appver=1.0&"
205             "pver=2.2&evts=malblhit&evtd=http%3A%2F%2Fmalicious.url.com%2F&"
206             "evtr=http%3A%2F%2Fpage.url.com%2F&evhr=http%3A%2F%2Freferrer."
207             "url.com%2F&evtb=1",
208             pm.SafeBrowsingHitUrl(
209                 malicious_url, page_url, referrer_url,
210                 true, SafeBrowsingService::URL_MALWARE).spec());
211 
212   pm.set_additional_query(kAdditionalQuery);
213   EXPECT_EQ("http://info.prefix.com/foo/report?client=unittest&appver=1.0&"
214             "pver=2.2&additional_query&evts=phishblhit&"
215             "evtd=http%3A%2F%2Fmalicious.url.com%2F&"
216             "evtr=http%3A%2F%2Fpage.url.com%2F&evhr=http%3A%2F%2Freferrer."
217             "url.com%2F&evtb=0",
218             pm.SafeBrowsingHitUrl(
219                 malicious_url, page_url, referrer_url,
220                 false, SafeBrowsingService::URL_PHISHING).spec());
221 
222   EXPECT_EQ("http://info.prefix.com/foo/report?client=unittest&appver=1.0&"
223             "pver=2.2&additional_query&evts=binurlhit&"
224             "evtd=http%3A%2F%2Fmalicious.url.com%2F&"
225             "evtr=http%3A%2F%2Fpage.url.com%2F&evhr=http%3A%2F%2Freferrer."
226             "url.com%2F&evtb=0",
227             pm.SafeBrowsingHitUrl(
228                 malicious_url, page_url, referrer_url,
229                 false, SafeBrowsingService::BINARY_MALWARE_URL).spec());
230 
231   EXPECT_EQ("http://info.prefix.com/foo/report?client=unittest&appver=1.0&"
232             "pver=2.2&additional_query&evts=binhashhit&"
233             "evtd=http%3A%2F%2Fmalicious.url.com%2F&"
234             "evtr=http%3A%2F%2Fpage.url.com%2F&evhr=http%3A%2F%2Freferrer."
235             "url.com%2F&evtb=0",
236             pm.SafeBrowsingHitUrl(
237                 malicious_url, page_url, referrer_url,
238                 false, SafeBrowsingService::BINARY_MALWARE_HASH).spec());
239 }
240 
TEST_F(SafeBrowsingProtocolManagerTest,TestMalwareDetailsUrl)241 TEST_F(SafeBrowsingProtocolManagerTest, TestMalwareDetailsUrl) {
242   SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
243                                  kInfoUrlPrefix, kMacKeyUrlPrefix, false);
244 
245   pm.version_ = kAppVer;
246   pm.set_additional_query(kAdditionalQuery);  // AdditionalQuery is not used.
247   EXPECT_EQ("https://key.prefix.com/bar/clientreport/malware?"
248             "client=unittest&appver=1.0&pver=1.0",
249             pm.MalwareDetailsUrl().spec());
250 }
251 
TEST_F(SafeBrowsingProtocolManagerTest,TestMacKeyUrl)252 TEST_F(SafeBrowsingProtocolManagerTest, TestMacKeyUrl) {
253   SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
254                                  kInfoUrlPrefix, kMacKeyUrlPrefix, false);
255   pm.version_ = kAppVer;
256 
257   EXPECT_EQ("https://key.prefix.com/bar/newkey?client=unittest&appver=1.0&"
258             "pver=2.2", pm.MacKeyUrl().spec());
259 
260   pm.set_additional_query(kAdditionalQuery);
261   EXPECT_EQ("https://key.prefix.com/bar/newkey?client=unittest&appver=1.0&"
262             "pver=2.2&additional_query", pm.MacKeyUrl().spec());
263 }
264 
TEST_F(SafeBrowsingProtocolManagerTest,TestNextChunkUrl)265 TEST_F(SafeBrowsingProtocolManagerTest, TestNextChunkUrl) {
266   SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
267                                  kInfoUrlPrefix, kMacKeyUrlPrefix, false);
268   pm.version_ = kAppVer;
269 
270   std::string url_partial = "localhost:1234/foo/bar?foo";
271   std::string url_http_full = "http://localhost:1234/foo/bar?foo";
272   std::string url_https_full = "https://localhost:1234/foo/bar?foo";
273   std::string url_https_no_query = "https://localhost:1234/foo/bar";
274 
275   EXPECT_EQ("http://localhost:1234/foo/bar?foo",
276             pm.NextChunkUrl(url_partial).spec());
277   EXPECT_EQ("http://localhost:1234/foo/bar?foo",
278             pm.NextChunkUrl(url_http_full).spec());
279   EXPECT_EQ("https://localhost:1234/foo/bar?foo",
280             pm.NextChunkUrl(url_https_full).spec());
281   EXPECT_EQ("https://localhost:1234/foo/bar",
282             pm.NextChunkUrl(url_https_no_query).spec());
283 
284   pm.set_additional_query(kAdditionalQuery);
285   EXPECT_EQ("http://localhost:1234/foo/bar?foo&additional_query",
286             pm.NextChunkUrl(url_partial).spec());
287   EXPECT_EQ("http://localhost:1234/foo/bar?foo&additional_query",
288             pm.NextChunkUrl(url_http_full).spec());
289   EXPECT_EQ("https://localhost:1234/foo/bar?foo&additional_query",
290             pm.NextChunkUrl(url_https_full).spec());
291   EXPECT_EQ("https://localhost:1234/foo/bar?additional_query",
292             pm.NextChunkUrl(url_https_no_query).spec());
293 }
294