| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 #include <memory> | 5 #include <memory> |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "base/base_switches.h" | 8 #include "base/base_switches.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/json/json_file_value_serializer.h" | 12 #include "base/json/json_file_value_serializer.h" |
| 13 #include "base/json/json_reader.h" |
| 13 #include "base/metrics/histogram_base.h" | 14 #include "base/metrics/histogram_base.h" |
| 14 #include "base/metrics/histogram_samples.h" | 15 #include "base/metrics/histogram_samples.h" |
| 15 #include "base/metrics/statistics_recorder.h" | 16 #include "base/metrics/statistics_recorder.h" |
| 16 #include "base/path_service.h" | 17 #include "base/path_service.h" |
| 17 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 20 #include "base/strings/utf_string_conversions.h" |
| 19 #include "base/values.h" | 21 #include "base/values.h" |
| 20 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 21 #include "chrome/browser/extensions/extension_browsertest.h" | 23 #include "chrome/browser/extensions/extension_browsertest.h" |
| 22 #include "chrome/browser/extensions/extension_service.h" | 24 #include "chrome/browser/extensions/extension_service.h" |
| 23 #include "chrome/browser/prefs/chrome_pref_service_factory.h" | 25 #include "chrome/browser/prefs/chrome_pref_service_factory.h" |
| 24 #include "chrome/browser/prefs/profile_pref_store_manager.h" | 26 #include "chrome/browser/prefs/profile_pref_store_manager.h" |
| 25 #include "chrome/browser/prefs/session_startup_pref.h" | 27 #include "chrome/browser/prefs/session_startup_pref.h" |
| 26 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
| 27 #include "chrome/browser/ui/browser.h" | 29 #include "chrome/browser/ui/browser.h" |
| 28 #include "chrome/common/chrome_constants.h" | 30 #include "chrome/common/chrome_constants.h" |
| 29 #include "chrome/common/chrome_paths.h" | 31 #include "chrome/common/chrome_paths.h" |
| 30 #include "chrome/common/pref_names.h" | 32 #include "chrome/common/pref_names.h" |
| 31 #include "chrome/test/base/testing_profile.h" | 33 #include "chrome/test/base/testing_profile.h" |
| 32 #include "components/search_engines/default_search_manager.h" | 34 #include "components/search_engines/default_search_manager.h" |
| 35 #include "components/search_engines/template_url_data.h" |
| 33 #include "components/user_prefs/tracked/tracked_preference_histogram_names.h" | 36 #include "components/user_prefs/tracked/tracked_preference_histogram_names.h" |
| 34 #include "extensions/browser/pref_names.h" | 37 #include "extensions/browser/pref_names.h" |
| 35 #include "extensions/common/extension.h" | 38 #include "extensions/common/extension.h" |
| 36 | 39 |
| 37 #if defined(OS_CHROMEOS) | 40 #if defined(OS_CHROMEOS) |
| 38 #include "chromeos/chromeos_switches.h" | 41 #include "chromeos/chromeos_switches.h" |
| 39 #endif | 42 #endif |
| 40 | 43 |
| 41 #if defined(OS_WIN) | 44 #if defined(OS_WIN) |
| 42 #include "base/test/test_reg_util_win.h" | 45 #include "base/test/test_reg_util_win.h" |
| (...skipping 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 user_prefs::tracked::kTrackedPrefHistogramChanged, | 1167 user_prefs::tracked::kTrackedPrefHistogramChanged, |
| 1165 user_prefs::tracked::kTrackedPrefRegistryValidationSuffix, | 1168 user_prefs::tracked::kTrackedPrefRegistryValidationSuffix, |
| 1166 BEGIN_ALLOW_SINGLE_BUCKET + 2)); | 1169 BEGIN_ALLOW_SINGLE_BUCKET + 2)); |
| 1167 } | 1170 } |
| 1168 } | 1171 } |
| 1169 }; | 1172 }; |
| 1170 | 1173 |
| 1171 PREF_HASH_BROWSER_TEST(PrefHashBrowserTestRegistryValidationFailure, | 1174 PREF_HASH_BROWSER_TEST(PrefHashBrowserTestRegistryValidationFailure, |
| 1172 RegistryValidationFailure); | 1175 RegistryValidationFailure); |
| 1173 #endif | 1176 #endif |
| 1177 |
| 1178 // Verifies that all preferences related to choice of default search engine are |
| 1179 // protected. |
| 1180 class PrefHashBrowserTestDefaultSearch : public PrefHashBrowserTestBase { |
| 1181 public: |
| 1182 void SetupPreferences() override { |
| 1183 // Set user selected default search engine. |
| 1184 DefaultSearchManager default_search_manager( |
| 1185 profile()->GetPrefs(), DefaultSearchManager::ObserverCallback()); |
| 1186 DefaultSearchManager::Source dse_source = |
| 1187 static_cast<DefaultSearchManager::Source>(-1); |
| 1188 |
| 1189 TemplateURLData user_dse; |
| 1190 user_dse.SetKeyword(base::UTF8ToUTF16("userkeyword")); |
| 1191 user_dse.SetShortName(base::UTF8ToUTF16("username")); |
| 1192 user_dse.SetURL("http://user_default_engine/search?q=good_user_query"); |
| 1193 default_search_manager.SetUserSelectedDefaultSearchEngine(user_dse); |
| 1194 |
| 1195 const TemplateURLData* current_dse = |
| 1196 default_search_manager.GetDefaultSearchEngine(&dse_source); |
| 1197 EXPECT_EQ(DefaultSearchManager::FROM_USER, dse_source); |
| 1198 EXPECT_EQ(current_dse->keyword(), base::UTF8ToUTF16("userkeyword")); |
| 1199 EXPECT_EQ(current_dse->short_name(), base::UTF8ToUTF16("username")); |
| 1200 EXPECT_EQ(current_dse->url(), |
| 1201 "http://user_default_engine/search?q=good_user_query"); |
| 1202 } |
| 1203 |
| 1204 void AttackPreferencesOnDisk( |
| 1205 base::DictionaryValue* unprotected_preferences, |
| 1206 base::DictionaryValue* protected_preferences) override { |
| 1207 static constexpr char default_search_provider_data[] = R"( |
| 1208 { |
| 1209 "default_search_provider_data" : { |
| 1210 "template_url_data" : { |
| 1211 "keyword" : "badkeyword", |
| 1212 "short_name" : "badname", |
| 1213 "url" : "http://bad_default_engine/search?q=dirty_user_query" |
| 1214 } |
| 1215 } |
| 1216 })"; |
| 1217 static constexpr char search_provider_overrides[] = R"( |
| 1218 { |
| 1219 "search_provider_overrides" : [ |
| 1220 { |
| 1221 "keyword" : "badkeyword", |
| 1222 "name" : "badname", |
| 1223 "search_url" : "http://bad_default_engine/search?q=dirty_user_query", |
| 1224 "encoding" : "utf-8", |
| 1225 "id" : 1 |
| 1226 }, { |
| 1227 "keyword" : "badkeyword2", |
| 1228 "name" : "badname2", |
| 1229 "search_url" : "http://bad_default_engine2/search?q=dirty_user_query", |
| 1230 "encoding" : "utf-8", |
| 1231 "id" : 2 |
| 1232 } |
| 1233 ] |
| 1234 })"; |
| 1235 static constexpr char default_search_provider[] = R"( |
| 1236 { |
| 1237 "default_search_provider" : { |
| 1238 "keyword" : "badkeyword", |
| 1239 "name" : "badname", |
| 1240 "search_url" : "http://bad_default_engine/search?q=dirty_user_query" |
| 1241 } |
| 1242 })"; |
| 1243 |
| 1244 // Try to override default search in all three of available preferences. |
| 1245 auto attack1 = base::DictionaryValue::From( |
| 1246 base::JSONReader::Read(default_search_provider_data)); |
| 1247 auto attack2 = base::DictionaryValue::From( |
| 1248 base::JSONReader::Read(search_provider_overrides)); |
| 1249 auto attack3 = base::DictionaryValue::From( |
| 1250 base::JSONReader::Read(default_search_provider)); |
| 1251 unprotected_preferences->MergeDictionary(attack1.get()); |
| 1252 unprotected_preferences->MergeDictionary(attack2.get()); |
| 1253 unprotected_preferences->MergeDictionary(attack3.get()); |
| 1254 if (protected_preferences) { |
| 1255 // Override here, too. |
| 1256 protected_preferences->MergeDictionary(attack1.get()); |
| 1257 protected_preferences->MergeDictionary(attack2.get()); |
| 1258 protected_preferences->MergeDictionary(attack3.get()); |
| 1259 } |
| 1260 } |
| 1261 |
| 1262 void VerifyReactionToPrefAttack() override { |
| 1263 DefaultSearchManager default_search_manager( |
| 1264 profile()->GetPrefs(), DefaultSearchManager::ObserverCallback()); |
| 1265 DefaultSearchManager::Source dse_source = |
| 1266 static_cast<DefaultSearchManager::Source>(-1); |
| 1267 |
| 1268 const TemplateURLData* current_dse = |
| 1269 default_search_manager.GetDefaultSearchEngine(&dse_source); |
| 1270 |
| 1271 if (protection_level_ < PROTECTION_ENABLED_DSE) { |
| 1272 // This doesn't work on OS_CHROMEOS because we fail to attack Preferences. |
| 1273 #if !defined(OS_CHROMEOS) |
| 1274 // Attack is successful. |
| 1275 EXPECT_EQ(DefaultSearchManager::FROM_USER, dse_source); |
| 1276 EXPECT_EQ(current_dse->keyword(), base::UTF8ToUTF16("badkeyword")); |
| 1277 EXPECT_EQ(current_dse->short_name(), base::UTF8ToUTF16("badname")); |
| 1278 EXPECT_EQ(current_dse->url(), |
| 1279 "http://bad_default_engine/search?q=dirty_user_query"); |
| 1280 #endif |
| 1281 } else { |
| 1282 // Attack fails. |
| 1283 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, dse_source); |
| 1284 EXPECT_NE(current_dse->keyword(), base::UTF8ToUTF16("badkeyword")); |
| 1285 EXPECT_NE(current_dse->short_name(), base::UTF8ToUTF16("badname")); |
| 1286 EXPECT_NE(current_dse->url(), |
| 1287 "http://bad_default_engine/search?q=dirty_user_query"); |
| 1288 } |
| 1289 } |
| 1290 }; |
| 1291 |
| 1292 PREF_HASH_BROWSER_TEST(PrefHashBrowserTestDefaultSearch, SearchProtected); |
| OLD | NEW |