Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: chrome/browser/extensions/updater/extension_downloader.cc

Issue 10446027: Force update checks to use SSL for store-hosted extensions/apps. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ready for review Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/extensions/updater/extension_updater_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "chrome/browser/extensions/updater/extension_downloader.h" 5 #include "chrome/browser/extensions/updater/extension_downloader.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 return false; 143 return false;
144 } 144 }
145 145
146 // If the extension updates itself from the gallery, ignore any update URL 146 // If the extension updates itself from the gallery, ignore any update URL
147 // data. At the moment there is no extra data that an extension can 147 // data. At the moment there is no extra data that an extension can
148 // communicate to the the gallery update servers. 148 // communicate to the the gallery update servers.
149 std::string update_url_data; 149 std::string update_url_data;
150 if (!extension.UpdatesFromGallery()) 150 if (!extension.UpdatesFromGallery())
151 update_url_data = delegate_->GetUpdateUrlData(extension.id()); 151 update_url_data = delegate_->GetUpdateUrlData(extension.id());
152 152
153 // Make sure we use SSL for store-hosted extensions.
154 GURL update_url = extension.update_url();
155 if (extension.UpdatesFromGallery() && !update_url.SchemeIsSecure())
156 update_url = extension_urls::GetWebstoreUpdateUrl();
157
153 return AddExtensionData(extension.id(), *extension.version(), 158 return AddExtensionData(extension.id(), *extension.version(),
154 extension.GetType(), extension.update_url(), 159 extension.GetType(), update_url,
155 update_url_data); 160 update_url_data);
156 } 161 }
157 162
158 bool ExtensionDownloader::AddPendingExtension(const std::string& id, 163 bool ExtensionDownloader::AddPendingExtension(const std::string& id,
159 const GURL& update_url) { 164 const GURL& update_url) {
160 // Use a zero version to ensure that a pending extension will always 165 // Use a zero version to ensure that a pending extension will always
161 // be updated, and thus installed (assuming all extensions have 166 // be updated, and thus installed (assuming all extensions have
162 // non-zero versions). 167 // non-zero versions).
163 Version version("0.0.0.0"); 168 Version version("0.0.0.0");
164 DCHECK(version.IsValid()); 169 DCHECK(version.IsValid());
(...skipping 15 matching lines...) Expand all
180 fetches_preparing_.clear(); 185 fetches_preparing_.clear();
181 } 186 }
182 187
183 void ExtensionDownloader::StartBlacklistUpdate( 188 void ExtensionDownloader::StartBlacklistUpdate(
184 const std::string& version, 189 const std::string& version,
185 const ManifestFetchData::PingData& ping_data) { 190 const ManifestFetchData::PingData& ping_data) {
186 // Note: it is very important that we use the https version of the update 191 // Note: it is very important that we use the https version of the update
187 // url here to avoid DNS hijacking of the blacklist, which is not validated 192 // url here to avoid DNS hijacking of the blacklist, which is not validated
188 // by a public key signature like .crx files are. 193 // by a public key signature like .crx files are.
189 ManifestFetchData* blacklist_fetch = 194 ManifestFetchData* blacklist_fetch =
190 new ManifestFetchData(extension_urls::GetWebstoreUpdateUrl(true)); 195 new ManifestFetchData(extension_urls::GetWebstoreUpdateUrl());
196 DCHECK(blacklist_fetch->base_url().SchemeIsSecure());
191 blacklist_fetch->AddExtension(kBlacklistAppID, version, &ping_data, "", 197 blacklist_fetch->AddExtension(kBlacklistAppID, version, &ping_data, "",
192 kDefaultInstallSource); 198 kDefaultInstallSource);
193 StartUpdateCheck(blacklist_fetch); 199 StartUpdateCheck(blacklist_fetch);
194 } 200 }
195 201
196 bool ExtensionDownloader::AddExtensionData(const std::string& id, 202 bool ExtensionDownloader::AddExtensionData(const std::string& id,
197 const Version& version, 203 const Version& version,
198 Extension::Type extension_type, 204 Extension::Type extension_type,
199 GURL update_url, 205 GURL update_url,
200 const std::string& update_url_data) { 206 const std::string& update_url_data) {
201 // Skip extensions with non-empty invalid update URLs. 207 // Skip extensions with non-empty invalid update URLs.
202 if (!update_url.is_empty() && !update_url.is_valid()) { 208 if (!update_url.is_empty() && !update_url.is_valid()) {
203 LOG(WARNING) << "Extension " << id << " has invalid update url " 209 LOG(WARNING) << "Extension " << id << " has invalid update url "
204 << update_url; 210 << update_url;
205 return false; 211 return false;
206 } 212 }
207 213
214 // Double-check that we're using https for webstore urls.
215 if (extension_urls::IsWebstoreUpdateUrl(update_url) &&
216 !update_url.SchemeIsSecure() &&
217 extension_urls::GetWebstoreUpdateUrl().SchemeIsSecure()) {
218 NOTREACHED() << "Refusing to send non-secure update check for " << id
219 << " (" << update_url.spec() << ")";
220 return false;
221 }
222
208 // Skip extensions with empty IDs. 223 // Skip extensions with empty IDs.
209 if (id.empty()) { 224 if (id.empty()) {
210 LOG(WARNING) << "Found extension with empty ID"; 225 LOG(WARNING) << "Found extension with empty ID";
211 return false; 226 return false;
212 } 227 }
213 228
214 if (update_url.DomainIs("google.com")) { 229 if (update_url.DomainIs("google.com")) {
215 url_stats_.google_url_count++; 230 url_stats_.google_url_count++;
216 } else if (update_url.is_empty()) { 231 } else if (update_url.is_empty()) {
217 url_stats_.no_url_count++; 232 url_stats_.no_url_count++;
218 // Fill in default update URL. 233 // Fill in default update URL.
219 // 234 update_url = extension_urls::GetWebstoreUpdateUrl();
220 // TODO(akalin): Figure out if we should use the HTTPS version.
221 update_url = extension_urls::GetWebstoreUpdateUrl(false);
222 } else { 235 } else {
223 url_stats_.other_url_count++; 236 url_stats_.other_url_count++;
224 } 237 }
225 238
226 switch (extension_type) { 239 switch (extension_type) {
227 case Extension::TYPE_THEME: 240 case Extension::TYPE_THEME:
228 ++url_stats_.theme_count; 241 ++url_stats_.theme_count;
229 break; 242 break;
230 case Extension::TYPE_EXTENSION: 243 case Extension::TYPE_EXTENSION:
231 case Extension::TYPE_USER_SCRIPT: 244 case Extension::TYPE_USER_SCRIPT:
232 ++url_stats_.extension_count; 245 ++url_stats_.extension_count;
233 break; 246 break;
234 case Extension::TYPE_HOSTED_APP: 247 case Extension::TYPE_HOSTED_APP:
235 case Extension::TYPE_PACKAGED_APP: 248 case Extension::TYPE_PACKAGED_APP:
236 ++url_stats_.app_count; 249 ++url_stats_.app_count;
237 break; 250 break;
238 case Extension::TYPE_UNKNOWN: 251 case Extension::TYPE_UNKNOWN:
239 default: 252 default:
240 ++url_stats_.pending_count; 253 ++url_stats_.pending_count;
241 break; 254 break;
242 } 255 }
243 256
244 std::vector<GURL> update_urls; 257 std::vector<GURL> update_urls;
245 update_urls.push_back(update_url); 258 update_urls.push_back(update_url);
246 // If UMA is enabled, also add to ManifestFetchData for the 259 // If UMA is enabled, also add to ManifestFetchData for the
247 // webstore update URL. 260 // webstore update URL.
248 if (!extension_urls::IsWebstoreUpdateUrl(update_url) && 261 if (!extension_urls::IsWebstoreUpdateUrl(update_url) &&
249 MetricsServiceHelper::IsMetricsReportingEnabled()) { 262 MetricsServiceHelper::IsMetricsReportingEnabled()) {
250 update_urls.push_back(extension_urls::GetWebstoreUpdateUrl(false)); 263 update_urls.push_back(extension_urls::GetWebstoreUpdateUrl());
251 } 264 }
252 265
253 for (size_t i = 0; i < update_urls.size(); ++i) { 266 for (size_t i = 0; i < update_urls.size(); ++i) {
254 DCHECK(!update_urls[i].is_empty()); 267 DCHECK(!update_urls[i].is_empty());
255 DCHECK(update_urls[i].is_valid()); 268 DCHECK(update_urls[i].is_valid());
256 269
257 std::string install_source = i == 0 ? 270 std::string install_source = i == 0 ?
258 kDefaultInstallSource : kNotFromWebstoreInstallSource; 271 kDefaultInstallSource : kNotFromWebstoreInstallSource;
259 272
260 ManifestFetchData::PingData ping_data; 273 ManifestFetchData::PingData ping_data;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 return; 438 return;
426 } 439 }
427 440
428 // Examine the parsed manifest and kick off fetches of any new crx files. 441 // Examine the parsed manifest and kick off fetches of any new crx files.
429 std::vector<int> updates; 442 std::vector<int> updates;
430 DetermineUpdates(fetch_data, *results, &updates); 443 DetermineUpdates(fetch_data, *results, &updates);
431 for (size_t i = 0; i < updates.size(); i++) { 444 for (size_t i = 0; i < updates.size(); i++) {
432 const UpdateManifest::Result* update = &(results->list.at(updates[i])); 445 const UpdateManifest::Result* update = &(results->list.at(updates[i]));
433 const std::string& id = update->extension_id; 446 const std::string& id = update->extension_id;
434 not_updated.erase(id); 447 not_updated.erase(id);
448
449 GURL crx_url = update->crx_url;
435 if (id != kBlacklistAppID) { 450 if (id != kBlacklistAppID) {
436 NotifyUpdateFound(update->extension_id); 451 NotifyUpdateFound(update->extension_id);
437 } else { 452 } else {
438 // The URL of the blacklist file is returned by the server and we need to 453 // The URL of the blacklist file is returned by the server and we need to
439 // be sure that we continue to be able to reliably detect whether a URL 454 // be sure that we continue to be able to reliably detect whether a URL
440 // references a blacklist file. 455 // references a blacklist file.
441 DCHECK(extension_urls::IsBlacklistUpdateUrl(update->crx_url)) 456 DCHECK(extension_urls::IsBlacklistUpdateUrl(crx_url)) << crx_url;
442 << update->crx_url; 457
458 // Force https (crbug.com/129587).
459 if (!crx_url.SchemeIsSecure()) {
Aaron Boodman 2012/05/24 23:17:41 Will this affect non-store updates?
asargent_no_longer_on_chrome 2012/05/24 23:23:53 No, this is in the else block for the "if (id != k
460 url_canon::Replacements<char> replacements;
461 std::string scheme("https");
462 replacements.SetScheme(scheme.c_str(),
463 url_parse::Component(0, scheme.size()));
464 crx_url = crx_url.ReplaceComponents(replacements);
465 }
443 } 466 }
444 FetchUpdatedExtension(update->extension_id, update->crx_url, 467 FetchUpdatedExtension(update->extension_id, crx_url, update->package_hash,
445 update->package_hash, update->version); 468 update->version);
446 } 469 }
447 470
448 // If the manifest response included a <daystart> element, we want to save 471 // If the manifest response included a <daystart> element, we want to save
449 // that value for any extensions which had sent a ping in the request. 472 // that value for any extensions which had sent a ping in the request.
450 if (fetch_data.base_url().DomainIs("google.com") && 473 if (fetch_data.base_url().DomainIs("google.com") &&
451 results->daystart_elapsed_seconds >= 0) { 474 results->daystart_elapsed_seconds >= 0) {
452 Time day_start = 475 Time day_start =
453 Time::Now() - TimeDelta::FromSeconds(results->daystart_elapsed_seconds); 476 Time::Now() - TimeDelta::FromSeconds(results->daystart_elapsed_seconds);
454 477
455 const std::set<std::string>& extension_ids = fetch_data.extension_ids(); 478 const std::set<std::string>& extension_ids = fetch_data.extension_ids();
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 } 665 }
643 666
644 void ExtensionDownloader::NotifyUpdateFound(const std::string& id) { 667 void ExtensionDownloader::NotifyUpdateFound(const std::string& id) {
645 content::NotificationService::current()->Notify( 668 content::NotificationService::current()->Notify(
646 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND, 669 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
647 content::NotificationService::AllBrowserContextsAndSources(), 670 content::NotificationService::AllBrowserContextsAndSources(),
648 content::Details<const std::string>(&id)); 671 content::Details<const std::string>(&id));
649 } 672 }
650 673
651 } // namespace extensions 674 } // namespace extensions
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/extensions/updater/extension_updater_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698