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

Side by Side Diff: chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc

Issue 2454563003: Fix web accessible resource checks in ShouldAllowOpenURL (Closed)
Patch Set: Charlie's comments Created 4 years, 1 month 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 "chrome/browser/extensions/chrome_content_browser_client_extensions_par t.h" 5 #include "chrome/browser/extensions/chrome_content_browser_client_extensions_par t.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <set> 9 #include <set>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/debug/alias.h"
13 #include "base/debug/dump_without_crashing.h"
14 #include "base/metrics/histogram_macros.h"
12 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/extensions/extension_service.h" 16 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_web_ui.h" 17 #include "chrome/browser/extensions/extension_web_ui.h"
15 #include "chrome/browser/extensions/extension_webkit_preferences.h" 18 #include "chrome/browser/extensions/extension_webkit_preferences.h"
16 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" 19 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
17 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_io_data.h" 21 #include "chrome/browser/profiles/profile_io_data.h"
19 #include "chrome/browser/profiles/profile_manager.h" 22 #include "chrome/browser/profiles/profile_manager.h"
20 #include "chrome/browser/renderer_host/chrome_extension_message_filter.h" 23 #include "chrome/browser/renderer_host/chrome_extension_message_filter.h"
21 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" 24 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 // below. Extension, and isolated apps require different privileges to be 79 // below. Extension, and isolated apps require different privileges to be
77 // granted to their RenderProcessHosts. This classification allows us to make 80 // granted to their RenderProcessHosts. This classification allows us to make
78 // sure URLs are served by hosts with the right set of privileges. 81 // sure URLs are served by hosts with the right set of privileges.
79 enum RenderProcessHostPrivilege { 82 enum RenderProcessHostPrivilege {
80 PRIV_NORMAL, 83 PRIV_NORMAL,
81 PRIV_HOSTED, 84 PRIV_HOSTED,
82 PRIV_ISOLATED, 85 PRIV_ISOLATED,
83 PRIV_EXTENSION, 86 PRIV_EXTENSION,
84 }; 87 };
85 88
89 // Specifies reasons why web-accessible resource checks in ShouldAllowOpenURL
90 // might fail.
91 //
92 // This enum backs an UMA histogram. The order of existing values
93 // should not be changed, and new values should only be added before
94 // FAILURE_LAST.
95 enum ShouldAllowOpenURLFailureReason {
96 FAILURE_FILE_SYSTEM_URL = 0,
97 FAILURE_BLOB_URL,
98 FAILURE_SCHEME_NOT_HTTP_OR_HTTPS_OR_EXTENSION,
99 FAILURE_RESOURCE_NOT_WEB_ACCESSIBLE,
100 FAILURE_LAST,
101 };
102
86 RenderProcessHostPrivilege GetPrivilegeRequiredByUrl( 103 RenderProcessHostPrivilege GetPrivilegeRequiredByUrl(
87 const GURL& url, 104 const GURL& url,
88 ExtensionRegistry* registry) { 105 ExtensionRegistry* registry) {
89 // Default to a normal renderer cause it is lower privileged. This should only 106 // Default to a normal renderer cause it is lower privileged. This should only
90 // occur if the URL on a site instance is either malformed, or uninitialized. 107 // occur if the URL on a site instance is either malformed, or uninitialized.
91 // If it is malformed, then there is no need for better privileges anyways. 108 // If it is malformed, then there is no need for better privileges anyways.
92 // If it is uninitialized, but eventually settles on being an a scheme other 109 // If it is uninitialized, but eventually settles on being an a scheme other
93 // than normal webrenderer, the navigation logic will correct us out of band 110 // than normal webrenderer, the navigation logic will correct us out of band
94 // anyways. 111 // anyways.
95 if (!url.is_valid()) 112 if (!url.is_valid())
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 const Extension* extension = 506 const Extension* extension =
490 extension_info_map->extensions().GetExtensionOrAppByURL(first_party_url); 507 extension_info_map->extensions().GetExtensionOrAppByURL(first_party_url);
491 // Don't allow a service worker for an extension url with no extension (this 508 // Don't allow a service worker for an extension url with no extension (this
492 // could happen in the case of, e.g., an unloaded extension). 509 // could happen in the case of, e.g., an unloaded extension).
493 return extension != nullptr; 510 return extension != nullptr;
494 } 511 }
495 512
496 // static 513 // static
497 bool ChromeContentBrowserClientExtensionsPart::ShouldAllowOpenURL( 514 bool ChromeContentBrowserClientExtensionsPart::ShouldAllowOpenURL(
498 content::SiteInstance* site_instance, 515 content::SiteInstance* site_instance,
499 const GURL& from_url,
500 const GURL& to_url, 516 const GURL& to_url,
501 bool* result) { 517 bool* result) {
502 DCHECK(result); 518 DCHECK(result);
503 519
520 // Using url::Origin is important to properly handle blob: and filesystem:
521 // URLs.
522 url::Origin to_origin(to_url);
523 if (to_origin.scheme() != kExtensionScheme) {
524 // We're not responsible for protecting this resource. Note that hosted
525 // apps fall into this category.
526 return false;
527 }
528
504 // Do not allow pages from the web or other extensions navigate to 529 // Do not allow pages from the web or other extensions navigate to
505 // non-web-accessible extension resources. 530 // non-web-accessible extension resources.
506 if (to_url.SchemeIs(kExtensionScheme) && 531
507 (from_url.SchemeIsHTTPOrHTTPS() || from_url.SchemeIs(kExtensionScheme))) { 532 Profile* profile = Profile::FromBrowserContext(
508 Profile* profile = Profile::FromBrowserContext( 533 site_instance->GetProcess()->GetBrowserContext());
509 site_instance->GetProcess()->GetBrowserContext()); 534 ExtensionRegistry* registry = ExtensionRegistry::Get(profile);
510 ExtensionRegistry* registry = ExtensionRegistry::Get(profile); 535 if (!registry) {
511 if (!registry) { 536 *result = true;
512 *result = true; 537 return true;
513 return true; 538 }
539
540 const Extension* to_extension =
541 registry->enabled_extensions().GetByID(to_origin.host());
542 if (!to_extension) {
543 *result = true;
544 return true;
545 }
546
547 GURL site_url(site_instance->GetSiteURL());
548 const Extension* from_extension =
549 registry->enabled_extensions().GetExtensionOrAppByURL(site_url);
550 if (from_extension && from_extension->id() == to_extension->id()) {
551 *result = true;
552 return true;
553 }
554
555 // Blob and filesystem URLs are never considered web-accessible. See
556 // https://crbug.com/656752.
557 if (to_url.SchemeIsFileSystem() || to_url.SchemeIsBlob()) {
558 if (to_url.SchemeIsFileSystem()) {
559 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure",
560 FAILURE_FILE_SYSTEM_URL, FAILURE_LAST);
561 } else {
562 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure",
563 FAILURE_BLOB_URL, FAILURE_LAST);
Alexei Svitkine (slow) 2016/11/02 16:35:47 Please make a helper function to log this histogra
alexmos 2016/11/02 17:32:46 Done.
514 } 564 }
515 const Extension* extension = 565 // TODO(alexmos): Temporary instrumentation to find any regressions for
516 registry->enabled_extensions().GetExtensionOrAppByURL(to_url); 566 // this blocking. Remove after verifying that this is not breaking any
517 if (!extension) { 567 // legitimate use cases.
518 *result = true; 568 char site_url_copy[256];
519 return true; 569 base::strlcpy(site_url_copy, site_url.spec().c_str(),
520 } 570 arraysize(site_url_copy));
521 const Extension* from_extension = 571 base::debug::Alias(&site_url_copy);
522 registry->enabled_extensions().GetExtensionOrAppByURL( 572 char to_origin_copy[256];
523 site_instance->GetSiteURL()); 573 base::strlcpy(to_origin_copy, to_origin.Serialize().c_str(),
524 if (from_extension && from_extension->id() == extension->id()) { 574 arraysize(to_origin_copy));
525 *result = true; 575 base::debug::Alias(&to_origin_copy);
526 return true; 576 base::debug::DumpWithoutCrashing();
527 }
528 577
529 if (!WebAccessibleResourcesInfo::IsResourceWebAccessible( 578 *result = false;
530 extension, to_url.path())) { 579 return true;
531 *result = false;
532 return true;
533 }
534 } 580 }
535 return false; 581
582 if (WebAccessibleResourcesInfo::IsResourceWebAccessible(to_extension,
583 to_url.path())) {
584 *result = true;
585 return true;
586 }
587
588 if (!site_url.SchemeIsHTTPOrHTTPS() && !site_url.SchemeIs(kExtensionScheme)) {
589 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure",
590 FAILURE_SCHEME_NOT_HTTP_OR_HTTPS_OR_EXTENSION,
591 FAILURE_LAST);
592 // TODO(alexmos): Previous version of this function skipped the
593 // web-accessible resource checks in this case. Collect data to catch
594 // any regressions, and then remove this.
595 char site_url_copy[256];
596 base::strlcpy(site_url_copy, site_url.spec().c_str(),
597 arraysize(site_url_copy));
598 base::debug::Alias(&site_url_copy);
599 char to_origin_copy[256];
600 base::strlcpy(to_origin_copy, to_origin.Serialize().c_str(),
601 arraysize(to_origin_copy));
602 base::debug::Alias(&to_origin_copy);
603 base::debug::DumpWithoutCrashing();
604 } else {
605 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure",
606 FAILURE_RESOURCE_NOT_WEB_ACCESSIBLE,
607 FAILURE_LAST);
608 }
609
610 *result = false;
611 return true;
536 } 612 }
537 613
538 // static 614 // static
539 std::unique_ptr<content::VpnServiceProxy> 615 std::unique_ptr<content::VpnServiceProxy>
540 ChromeContentBrowserClientExtensionsPart::GetVpnServiceProxy( 616 ChromeContentBrowserClientExtensionsPart::GetVpnServiceProxy(
541 content::BrowserContext* browser_context) { 617 content::BrowserContext* browser_context) {
542 #if defined(OS_CHROMEOS) 618 #if defined(OS_CHROMEOS)
543 chromeos::VpnService* vpn_service = 619 chromeos::VpnService* vpn_service =
544 chromeos::VpnServiceFactory::GetForBrowserContext(browser_context); 620 chromeos::VpnServiceFactory::GetForBrowserContext(browser_context);
545 if (!vpn_service) 621 if (!vpn_service)
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 command_line->AppendSwitch(switches::kExtensionProcess); 763 command_line->AppendSwitch(switches::kExtensionProcess);
688 } 764 }
689 } 765 }
690 766
691 void ChromeContentBrowserClientExtensionsPart::ResourceDispatcherHostCreated() { 767 void ChromeContentBrowserClientExtensionsPart::ResourceDispatcherHostCreated() {
692 content::ResourceDispatcherHost::Get()->RegisterInterceptor( 768 content::ResourceDispatcherHost::Get()->RegisterInterceptor(
693 "Origin", kExtensionScheme, base::Bind(&OnHttpHeaderReceived)); 769 "Origin", kExtensionScheme, base::Bind(&OnHttpHeaderReceived));
694 } 770 }
695 771
696 } // namespace extensions 772 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698