1 // Copyright 2014 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 "base/bind.h" 6 #include "base/bind_helpers.h" 7 #include "base/message_loop/message_loop.h" 8 #include "base/run_loop.h" 9 #include "chrome/browser/supervised_user/supervised_user_url_filter.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 #include "url/gurl.h" 12 13 class SupervisedUserURLFilterTest : public ::testing::Test, 14 public SupervisedUserURLFilter::Observer { 15 public: 16 SupervisedUserURLFilterTest() : filter_(new SupervisedUserURLFilter) { 17 filter_->SetDefaultFilteringBehavior(SupervisedUserURLFilter::BLOCK); 18 filter_->AddObserver(this); 19 } 20 21 virtual ~SupervisedUserURLFilterTest() { 22 filter_->RemoveObserver(this); 23 } 24 25 // SupervisedUserURLFilter::Observer: 26 virtual void OnSiteListUpdated() OVERRIDE { 27 run_loop_.Quit(); 28 } 29 30 protected: 31 bool IsURLWhitelisted(const std::string& url) { 32 return filter_->GetFilteringBehaviorForURL(GURL(url)) == 33 SupervisedUserURLFilter::ALLOW; 34 } 35 36 base::MessageLoop message_loop_; 37 base::RunLoop run_loop_; 38 scoped_refptr<SupervisedUserURLFilter> filter_; 39 }; 40 41 TEST_F(SupervisedUserURLFilterTest, Basic) { 42 std::vector<std::string> list; 43 // Allow domain and all subdomains, for any filtered scheme. 44 list.push_back("google.com"); 45 filter_->SetFromPatterns(list); 46 run_loop_.Run(); 47 48 EXPECT_TRUE(IsURLWhitelisted("http://google.com")); 49 EXPECT_TRUE(IsURLWhitelisted("http://google.com/")); 50 EXPECT_TRUE(IsURLWhitelisted("http://google.com/whatever")); 51 EXPECT_TRUE(IsURLWhitelisted("https://google.com/")); 52 EXPECT_FALSE(IsURLWhitelisted("http://notgoogle.com/")); 53 EXPECT_TRUE(IsURLWhitelisted("http://mail.google.com")); 54 EXPECT_TRUE(IsURLWhitelisted("http://x.mail.google.com")); 55 EXPECT_TRUE(IsURLWhitelisted("https://x.mail.google.com/")); 56 EXPECT_TRUE(IsURLWhitelisted("http://x.y.google.com/a/b")); 57 EXPECT_FALSE(IsURLWhitelisted("http://youtube.com/")); 58 59 EXPECT_TRUE(IsURLWhitelisted("bogus://youtube.com/")); 60 EXPECT_TRUE(IsURLWhitelisted("chrome://youtube.com/")); 61 EXPECT_TRUE(IsURLWhitelisted("chrome://extensions/")); 62 EXPECT_TRUE(IsURLWhitelisted("chrome-extension://foo/main.html")); 63 EXPECT_TRUE(IsURLWhitelisted("file:///home/chronos/user/Downloads/img.jpg")); 64 } 65 66 TEST_F(SupervisedUserURLFilterTest, Inactive) { 67 filter_->SetDefaultFilteringBehavior(SupervisedUserURLFilter::ALLOW); 68 69 std::vector<std::string> list; 70 list.push_back("google.com"); 71 filter_->SetFromPatterns(list); 72 run_loop_.Run(); 73 74 // If the filter is inactive, every URL should be whitelisted. 75 EXPECT_TRUE(IsURLWhitelisted("http://google.com")); 76 EXPECT_TRUE(IsURLWhitelisted("https://www.example.com")); 77 } 78 79 TEST_F(SupervisedUserURLFilterTest, Scheme) { 80 std::vector<std::string> list; 81 // Filter only http, ftp and ws schemes. 82 list.push_back("http://secure.com"); 83 list.push_back("ftp://secure.com"); 84 list.push_back("ws://secure.com"); 85 filter_->SetFromPatterns(list); 86 run_loop_.Run(); 87 88 EXPECT_TRUE(IsURLWhitelisted("http://secure.com")); 89 EXPECT_TRUE(IsURLWhitelisted("http://secure.com/whatever")); 90 EXPECT_TRUE(IsURLWhitelisted("ftp://secure.com/")); 91 EXPECT_TRUE(IsURLWhitelisted("ws://secure.com")); 92 EXPECT_FALSE(IsURLWhitelisted("https://secure.com/")); 93 EXPECT_FALSE(IsURLWhitelisted("wss://secure.com")); 94 EXPECT_TRUE(IsURLWhitelisted("http://www.secure.com")); 95 EXPECT_FALSE(IsURLWhitelisted("https://www.secure.com")); 96 EXPECT_FALSE(IsURLWhitelisted("wss://www.secure.com")); 97 } 98 99 TEST_F(SupervisedUserURLFilterTest, Path) { 100 std::vector<std::string> list; 101 // Filter only a certain path prefix. 102 list.push_back("path.to/ruin"); 103 filter_->SetFromPatterns(list); 104 run_loop_.Run(); 105 106 EXPECT_TRUE(IsURLWhitelisted("http://path.to/ruin")); 107 EXPECT_TRUE(IsURLWhitelisted("https://path.to/ruin")); 108 EXPECT_TRUE(IsURLWhitelisted("http://path.to/ruins")); 109 EXPECT_TRUE(IsURLWhitelisted("http://path.to/ruin/signup")); 110 EXPECT_TRUE(IsURLWhitelisted("http://www.path.to/ruin")); 111 EXPECT_FALSE(IsURLWhitelisted("http://path.to/fortune")); 112 } 113 114 TEST_F(SupervisedUserURLFilterTest, PathAndScheme) { 115 std::vector<std::string> list; 116 // Filter only a certain path prefix and scheme. 117 list.push_back("https://s.aaa.com/path"); 118 filter_->SetFromPatterns(list); 119 run_loop_.Run(); 120 121 EXPECT_TRUE(IsURLWhitelisted("https://s.aaa.com/path")); 122 EXPECT_TRUE(IsURLWhitelisted("https://s.aaa.com/path/bbb")); 123 EXPECT_FALSE(IsURLWhitelisted("http://s.aaa.com/path")); 124 EXPECT_FALSE(IsURLWhitelisted("https://aaa.com/path")); 125 EXPECT_FALSE(IsURLWhitelisted("https://x.aaa.com/path")); 126 EXPECT_FALSE(IsURLWhitelisted("https://s.aaa.com/bbb")); 127 EXPECT_FALSE(IsURLWhitelisted("https://s.aaa.com/")); 128 } 129 130 TEST_F(SupervisedUserURLFilterTest, Host) { 131 std::vector<std::string> list; 132 // Filter only a certain hostname, without subdomains. 133 list.push_back(".www.example.com"); 134 filter_->SetFromPatterns(list); 135 run_loop_.Run(); 136 137 EXPECT_TRUE(IsURLWhitelisted("http://www.example.com")); 138 EXPECT_FALSE(IsURLWhitelisted("http://example.com")); 139 EXPECT_FALSE(IsURLWhitelisted("http://subdomain.example.com")); 140 } 141 142 TEST_F(SupervisedUserURLFilterTest, IPAddress) { 143 std::vector<std::string> list; 144 // Filter an ip address. 145 list.push_back("123.123.123.123"); 146 filter_->SetFromPatterns(list); 147 run_loop_.Run(); 148 149 EXPECT_TRUE(IsURLWhitelisted("http://123.123.123.123/")); 150 EXPECT_FALSE(IsURLWhitelisted("http://123.123.123.124/")); 151 } 152 153 TEST_F(SupervisedUserURLFilterTest, Canonicalization) { 154 // We assume that the hosts and URLs are already canonicalized. 155 std::map<std::string, bool> hosts; 156 hosts["www.moose.org"] = true; 157 hosts["www.xn--n3h.net"] = true; 158 std::map<GURL, bool> urls; 159 urls[GURL("http://www.example.com/foo/")] = true; 160 urls[GURL("http://www.example.com/%C3%85t%C3%B8mstr%C3%B6m")] = true; 161 filter_->SetManualHosts(&hosts); 162 filter_->SetManualURLs(&urls); 163 164 // Base cases. 165 EXPECT_TRUE(IsURLWhitelisted("http://www.example.com/foo/")); 166 EXPECT_TRUE(IsURLWhitelisted( 167 "http://www.example.com/%C3%85t%C3%B8mstr%C3%B6m")); 168 169 // Verify that non-URI characters are escaped. 170 EXPECT_TRUE(IsURLWhitelisted( 171 "http://www.example.com/\xc3\x85t\xc3\xb8mstr\xc3\xb6m")); 172 173 // Verify that unnecessary URI escapes are unescaped. 174 EXPECT_TRUE(IsURLWhitelisted("http://www.example.com/%66%6F%6F/")); 175 176 // Verify that the default port are removed. 177 EXPECT_TRUE(IsURLWhitelisted("http://www.example.com:80/foo/")); 178 179 // Verify that scheme and hostname are lowercased. 180 EXPECT_TRUE(IsURLWhitelisted("htTp://wWw.eXamPle.com/foo/")); 181 EXPECT_TRUE(IsURLWhitelisted("HttP://WwW.mOOsE.orG/blurp/")); 182 183 // Verify that UTF-8 in hostnames are converted to punycode. 184 EXPECT_TRUE(IsURLWhitelisted("http://www.\xe2\x98\x83\x0a.net/bla/")); 185 186 // Verify that query and ref are stripped. 187 EXPECT_TRUE(IsURLWhitelisted("http://www.example.com/foo/?bar=baz#ref")); 188 } 189 190 TEST_F(SupervisedUserURLFilterTest, HasFilteredScheme) { 191 EXPECT_TRUE( 192 SupervisedUserURLFilter::HasFilteredScheme(GURL("http://example.com"))); 193 EXPECT_TRUE( 194 SupervisedUserURLFilter::HasFilteredScheme(GURL("https://example.com"))); 195 EXPECT_TRUE( 196 SupervisedUserURLFilter::HasFilteredScheme(GURL("ftp://example.com"))); 197 EXPECT_TRUE( 198 SupervisedUserURLFilter::HasFilteredScheme(GURL("gopher://example.com"))); 199 EXPECT_TRUE( 200 SupervisedUserURLFilter::HasFilteredScheme(GURL("ws://example.com"))); 201 EXPECT_TRUE( 202 SupervisedUserURLFilter::HasFilteredScheme(GURL("wss://example.com"))); 203 204 EXPECT_FALSE( 205 SupervisedUserURLFilter::HasFilteredScheme(GURL("file://example.com"))); 206 EXPECT_FALSE( 207 SupervisedUserURLFilter::HasFilteredScheme( 208 GURL("filesystem://80cols.com"))); 209 EXPECT_FALSE( 210 SupervisedUserURLFilter::HasFilteredScheme(GURL("chrome://example.com"))); 211 EXPECT_FALSE( 212 SupervisedUserURLFilter::HasFilteredScheme(GURL("wtf://example.com"))); 213 } 214 215 TEST_F(SupervisedUserURLFilterTest, HostMatchesPattern) { 216 EXPECT_TRUE( 217 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", 218 "*.google.com")); 219 EXPECT_TRUE( 220 SupervisedUserURLFilter::HostMatchesPattern("google.com", 221 "*.google.com")); 222 EXPECT_TRUE( 223 SupervisedUserURLFilter::HostMatchesPattern("accounts.google.com", 224 "*.google.com")); 225 EXPECT_FALSE( 226 SupervisedUserURLFilter::HostMatchesPattern("www.google.de", 227 "*.google.com")); 228 EXPECT_FALSE( 229 SupervisedUserURLFilter::HostMatchesPattern("notgoogle.com", 230 "*.google.com")); 231 232 233 EXPECT_TRUE( 234 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", 235 "www.google.*")); 236 EXPECT_TRUE( 237 SupervisedUserURLFilter::HostMatchesPattern("www.google.de", 238 "www.google.*")); 239 EXPECT_TRUE( 240 SupervisedUserURLFilter::HostMatchesPattern("www.google.co.uk", 241 "www.google.*")); 242 EXPECT_FALSE( 243 SupervisedUserURLFilter::HostMatchesPattern("www.google.blogspot.com", 244 "www.google.*")); 245 EXPECT_FALSE( 246 SupervisedUserURLFilter::HostMatchesPattern("www.google", 247 "www.google.*")); 248 EXPECT_FALSE( 249 SupervisedUserURLFilter::HostMatchesPattern("google.com", 250 "www.google.*")); 251 EXPECT_FALSE( 252 SupervisedUserURLFilter::HostMatchesPattern("mail.google.com", 253 "www.google.*")); 254 EXPECT_FALSE( 255 SupervisedUserURLFilter::HostMatchesPattern("www.googleplex.com", 256 "www.google.*")); 257 EXPECT_FALSE( 258 SupervisedUserURLFilter::HostMatchesPattern("www.googleco.uk", 259 "www.google.*")); 260 261 262 EXPECT_TRUE( 263 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", 264 "*.google.*")); 265 EXPECT_TRUE( 266 SupervisedUserURLFilter::HostMatchesPattern("google.com", 267 "*.google.*")); 268 EXPECT_TRUE( 269 SupervisedUserURLFilter::HostMatchesPattern("accounts.google.com", 270 "*.google.*")); 271 EXPECT_TRUE( 272 SupervisedUserURLFilter::HostMatchesPattern("mail.google.com", 273 "*.google.*")); 274 EXPECT_TRUE( 275 SupervisedUserURLFilter::HostMatchesPattern("www.google.de", 276 "*.google.*")); 277 EXPECT_TRUE( 278 SupervisedUserURLFilter::HostMatchesPattern("google.de", 279 "*.google.*")); 280 EXPECT_FALSE( 281 SupervisedUserURLFilter::HostMatchesPattern("google.blogspot.com", 282 "*.google.*")); 283 EXPECT_FALSE( 284 SupervisedUserURLFilter::HostMatchesPattern("google", "*.google.*")); 285 EXPECT_FALSE( 286 SupervisedUserURLFilter::HostMatchesPattern("notgoogle.com", 287 "*.google.*")); 288 EXPECT_FALSE( 289 SupervisedUserURLFilter::HostMatchesPattern("www.googleplex.com", 290 "*.google.*")); 291 292 // Now test a few invalid patterns. They should never match. 293 EXPECT_FALSE( 294 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "")); 295 EXPECT_FALSE( 296 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", ".")); 297 EXPECT_FALSE( 298 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "*")); 299 EXPECT_FALSE( 300 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", ".*")); 301 EXPECT_FALSE( 302 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "*.")); 303 EXPECT_FALSE( 304 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "*.*")); 305 EXPECT_FALSE( 306 SupervisedUserURLFilter::HostMatchesPattern("www.google..com", "*..*")); 307 EXPECT_FALSE( 308 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "*.*.com")); 309 EXPECT_FALSE( 310 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", "www.*.*")); 311 EXPECT_FALSE( 312 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", 313 "*.goo.*le.*")); 314 EXPECT_FALSE( 315 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", 316 "*google*")); 317 EXPECT_FALSE( 318 SupervisedUserURLFilter::HostMatchesPattern("www.google.com", 319 "www.*.google.com")); 320 } 321 322 TEST_F(SupervisedUserURLFilterTest, Patterns) { 323 std::map<std::string, bool> hosts; 324 325 // Initally, the second rule is ignored because has the same value as the 326 // default (block). When we change the default to allow, the first rule is 327 // ignored instead. 328 hosts["*.google.com"] = true; 329 hosts["www.google.*"] = false; 330 331 hosts["accounts.google.com"] = false; 332 hosts["mail.google.com"] = true; 333 filter_->SetManualHosts(&hosts); 334 335 // Initially, the default filtering behavior is BLOCK. 336 EXPECT_TRUE(IsURLWhitelisted("http://www.google.com/foo/")); 337 EXPECT_FALSE(IsURLWhitelisted("http://accounts.google.com/bar/")); 338 EXPECT_FALSE(IsURLWhitelisted("http://www.google.co.uk/blurp/")); 339 EXPECT_TRUE(IsURLWhitelisted("http://mail.google.com/moose/")); 340 341 filter_->SetDefaultFilteringBehavior(SupervisedUserURLFilter::ALLOW); 342 EXPECT_FALSE(IsURLWhitelisted("http://www.google.com/foo/")); 343 EXPECT_FALSE(IsURLWhitelisted("http://accounts.google.com/bar/")); 344 EXPECT_FALSE(IsURLWhitelisted("http://www.google.co.uk/blurp/")); 345 EXPECT_TRUE(IsURLWhitelisted("http://mail.google.com/moose/")); 346 } 347