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

Side by Side Diff: extensions/common/features/simple_feature.cc

Issue 2116293003: extensions: Generate hash of extension ID at a higher level Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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
OLDNEW
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 "extensions/common/features/simple_feature.h" 5 #include "extensions/common/features/simple_feature.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 17 matching lines...) Expand all
28 namespace extensions { 28 namespace extensions {
29 29
30 namespace { 30 namespace {
31 31
32 // A singleton copy of the --whitelisted-extension-id so that we don't need to 32 // A singleton copy of the --whitelisted-extension-id so that we don't need to
33 // copy it from the CommandLine each time. 33 // copy it from the CommandLine each time.
34 std::string* g_whitelisted_extension_id = NULL; 34 std::string* g_whitelisted_extension_id = NULL;
35 35
36 Feature::Availability IsAvailableToManifestForBind( 36 Feature::Availability IsAvailableToManifestForBind(
37 const std::string& extension_id, 37 const std::string& extension_id,
38 const std::string& hashed_id,
38 Manifest::Type type, 39 Manifest::Type type,
39 Manifest::Location location, 40 Manifest::Location location,
40 int manifest_version, 41 int manifest_version,
41 Feature::Platform platform, 42 Feature::Platform platform,
42 const Feature* feature) { 43 const Feature* feature) {
43 return feature->IsAvailableToManifest( 44 return feature->IsAvailableToManifest(extension_id, hashed_id, type, location,
44 extension_id, type, location, manifest_version, platform); 45 manifest_version, platform);
45 } 46 }
46 47
47 Feature::Availability IsAvailableToContextForBind(const Extension* extension, 48 Feature::Availability IsAvailableToContextForBind(const Extension* extension,
48 Feature::Context context, 49 Feature::Context context,
49 const GURL& url, 50 const GURL& url,
50 Feature::Platform platform, 51 Feature::Platform platform,
51 const Feature* feature) { 52 const Feature* feature) {
52 return feature->IsAvailableToContext(extension, context, url, platform); 53 return feature->IsAvailableToContext(extension, context, url, platform);
53 } 54 }
54 55
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 result = filter->Parse(dictionary); 357 result = filter->Parse(dictionary);
357 if (!result.empty()) 358 if (!result.empty())
358 break; 359 break;
359 } 360 }
360 361
361 return result; 362 return result;
362 } 363 }
363 364
364 Feature::Availability SimpleFeature::IsAvailableToManifest( 365 Feature::Availability SimpleFeature::IsAvailableToManifest(
365 const std::string& extension_id, 366 const std::string& extension_id,
367 const std::string& hashed_id,
366 Manifest::Type type, 368 Manifest::Type type,
367 Manifest::Location location, 369 Manifest::Location location,
368 int manifest_version, 370 int manifest_version,
369 Platform platform) const { 371 Platform platform) const {
370 // Check extension type first to avoid granting platform app permissions 372 // Check extension type first to avoid granting platform app permissions
371 // to component extensions. 373 // to component extensions.
372 // HACK(kalman): user script -> extension. Solve this in a more generic way 374 // HACK(kalman): user script -> extension. Solve this in a more generic way
373 // when we compile feature files. 375 // when we compile feature files.
374 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? 376 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ?
375 Manifest::TYPE_EXTENSION : type; 377 Manifest::TYPE_EXTENSION : type;
376 if (!extension_types_.empty() && 378 if (!extension_types_.empty() &&
377 !ContainsValue(extension_types_, type_to_check)) { 379 !ContainsValue(extension_types_, type_to_check)) {
378 return CreateAvailability(INVALID_TYPE, type); 380 return CreateAvailability(INVALID_TYPE, type);
379 } 381 }
380 382
381 if (IsIdInBlacklist(extension_id)) 383 if (IsIdInBlacklist(extension_id, hashed_id))
382 return CreateAvailability(FOUND_IN_BLACKLIST, type); 384 return CreateAvailability(FOUND_IN_BLACKLIST, type);
383 385
384 // TODO(benwells): don't grant all component extensions. 386 // TODO(benwells): don't grant all component extensions.
385 // See http://crbug.com/370375 for more details. 387 // See http://crbug.com/370375 for more details.
386 // Component extensions can access any feature. 388 // Component extensions can access any feature.
387 // NOTE: Deliberately does not match EXTERNAL_COMPONENT. 389 // NOTE: Deliberately does not match EXTERNAL_COMPONENT.
388 if (component_extensions_auto_granted_ && location == Manifest::COMPONENT) 390 if (component_extensions_auto_granted_ && location == Manifest::COMPONENT)
389 return CreateAvailability(IS_AVAILABLE, type); 391 return CreateAvailability(IS_AVAILABLE, type);
390 392
391 if (!whitelist_.empty() && !IsIdInWhitelist(extension_id) && 393 if (!whitelist_.empty() && !IsIdInWhitelist(extension_id, hashed_id) &&
392 !IsWhitelistedForTest(extension_id)) { 394 !IsWhitelistedForTest(extension_id) && !IsWhitelistedForTest(hashed_id)) {
393 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); 395 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type);
394 } 396 }
395 397
396 if (!MatchesManifestLocation(location)) 398 if (!MatchesManifestLocation(location))
397 return CreateAvailability(INVALID_LOCATION, type); 399 return CreateAvailability(INVALID_LOCATION, type);
398 400
399 if (!platforms_.empty() && !ContainsValue(platforms_, platform)) 401 if (!platforms_.empty() && !ContainsValue(platforms_, platform))
400 return CreateAvailability(INVALID_PLATFORM, type); 402 return CreateAvailability(INVALID_PLATFORM, type);
401 403
402 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) 404 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_)
403 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); 405 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type);
404 406
405 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_) 407 if (max_manifest_version_ != 0 && manifest_version > max_manifest_version_)
406 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type); 408 return CreateAvailability(INVALID_MAX_MANIFEST_VERSION, type);
407 409
408 if (!command_line_switch_.empty() && 410 if (!command_line_switch_.empty() &&
409 !IsCommandLineSwitchEnabled(command_line_switch_)) { 411 !IsCommandLineSwitchEnabled(command_line_switch_)) {
410 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type); 412 return CreateAvailability(MISSING_COMMAND_LINE_SWITCH, type);
411 } 413 }
412 414
413 for (const auto& filter : filters_) { 415 for (const auto& filter : filters_) {
414 Availability availability = filter->IsAvailableToManifest( 416 Availability availability = filter->IsAvailableToManifest(
415 extension_id, type, location, manifest_version, platform); 417 extension_id, type, location, manifest_version, platform);
416 if (!availability.is_available()) 418 if (!availability.is_available())
417 return availability; 419 return availability;
418 } 420 }
419 421
420 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind, 422 return CheckDependencies(base::Bind(&IsAvailableToManifestForBind,
421 extension_id, 423 extension_id, hashed_id, type, location,
422 type, 424 manifest_version, platform));
423 location,
424 manifest_version,
425 platform));
426 } 425 }
427 426
428 Feature::Availability SimpleFeature::IsAvailableToContext( 427 Feature::Availability SimpleFeature::IsAvailableToContext(
429 const Extension* extension, 428 const Extension* extension,
430 SimpleFeature::Context context, 429 SimpleFeature::Context context,
431 const GURL& url, 430 const GURL& url,
432 SimpleFeature::Platform platform) const { 431 SimpleFeature::Platform platform) const {
433 if (extension) { 432 if (extension) {
434 Availability result = IsAvailableToManifest(extension->id(), 433 Availability result = IsAvailableToManifest(
435 extension->GetType(), 434 extension->id(), HashedIdInHex(extension->id()), extension->GetType(),
436 extension->location(), 435 extension->location(), extension->manifest_version(), platform);
437 extension->manifest_version(),
438 platform);
439 if (!result.is_available()) 436 if (!result.is_available())
440 return result; 437 return result;
441 } 438 }
442 439
443 // TODO(lazyboy): This isn't quite right for Extension Service Worker 440 // TODO(lazyboy): This isn't quite right for Extension Service Worker
444 // extension API calls, since there's no guarantee that the extension is 441 // extension API calls, since there's no guarantee that the extension is
445 // "active" in current renderer process when the API permission check is 442 // "active" in current renderer process when the API permission check is
446 // done. 443 // done.
447 if (!contexts_.empty() && !ContainsValue(contexts_, context)) 444 if (!contexts_.empty() && !ContainsValue(contexts_, context))
448 return CreateAvailability(INVALID_CONTEXT, context); 445 return CreateAvailability(INVALID_CONTEXT, context);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 Context context) const { 557 Context context) const {
561 return Availability( 558 return Availability(
562 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(), 559 result, GetAvailabilityMessage(result, Manifest::TYPE_UNKNOWN, GURL(),
563 context)); 560 context));
564 } 561 }
565 562
566 bool SimpleFeature::IsInternal() const { 563 bool SimpleFeature::IsInternal() const {
567 return false; 564 return false;
568 } 565 }
569 566
570 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const { 567 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id,
571 return IsIdInList(extension_id, blacklist_); 568 const std::string& hashed_id) const {
569 return (IsIdInList(extension_id, blacklist_) ||
570 IsIdInList(hashed_id, blacklist_));
572 } 571 }
573 572
574 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { 573 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id,
575 return IsIdInList(extension_id, whitelist_); 574 const std::string& hashed_id) const {
575 return (IsIdInList(extension_id, whitelist_) ||
576 IsIdInList(hashed_id, whitelist_));
576 } 577 }
577 578
578 // static 579 // static
579 bool SimpleFeature::IsIdInArray(const std::string& extension_id, 580 bool SimpleFeature::IsIdInArray(const std::string& extension_id,
580 const char* const array[], 581 const char* const array[],
581 size_t array_length) { 582 size_t array_length) {
582 if (!IsValidExtensionId(extension_id)) 583 if (!IsValidExtensionId(extension_id))
583 return false; 584 return false;
584 585
585 const char* const* start = array; 586 const char* const* start = array;
586 const char* const* end = array + array_length; 587 const char* const* end = array + array_length;
587 588
588 return ((std::find(start, end, extension_id) != end) || 589 return (std::find(start, end, extension_id) != end);
589 (std::find(start, end, HashedIdInHex(extension_id)) != end));
590 } 590 }
591 591
592 // static 592 // static
593 bool SimpleFeature::IsIdInList(const std::string& extension_id, 593 bool SimpleFeature::IsIdInList(const std::string& extension_id,
594 const std::vector<std::string>& list) { 594 const std::vector<std::string>& list) {
595 if (!IsValidExtensionId(extension_id)) 595 if (!IsValidExtensionId(extension_id))
596 return false; 596 return false;
597 597
598 return (ContainsValue(list, extension_id) || 598 return ContainsValue(list, extension_id);
599 ContainsValue(list, HashedIdInHex(extension_id)));
600 } 599 }
601 600
602 bool SimpleFeature::MatchesManifestLocation( 601 bool SimpleFeature::MatchesManifestLocation(
603 Manifest::Location manifest_location) const { 602 Manifest::Location manifest_location) const {
604 switch (location_) { 603 switch (location_) {
605 case SimpleFeature::UNSPECIFIED_LOCATION: 604 case SimpleFeature::UNSPECIFIED_LOCATION:
606 return true; 605 return true;
607 case SimpleFeature::COMPONENT_LOCATION: 606 case SimpleFeature::COMPONENT_LOCATION:
608 return manifest_location == Manifest::COMPONENT; 607 return manifest_location == Manifest::COMPONENT;
609 case SimpleFeature::EXTERNAL_COMPONENT_LOCATION: 608 case SimpleFeature::EXTERNAL_COMPONENT_LOCATION:
(...skipping 24 matching lines...) Expand all
634 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { 633 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) {
635 // Belt-and-suspenders philosophy here. We should be pretty confident by this 634 // Belt-and-suspenders philosophy here. We should be pretty confident by this
636 // point that we've validated the extension ID format, but in case something 635 // point that we've validated the extension ID format, but in case something
637 // slips through, we avoid a class of attack where creative ID manipulation 636 // slips through, we avoid a class of attack where creative ID manipulation
638 // leads to hash collisions. 637 // leads to hash collisions.
639 // 128 bits / 4 = 32 mpdecimal characters 638 // 128 bits / 4 = 32 mpdecimal characters
640 return (extension_id.length() == 32); 639 return (extension_id.length() == 32);
641 } 640 }
642 641
643 } // namespace extensions 642 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/common/features/simple_feature.h ('k') | extensions/common/features/simple_feature_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698