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

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: Rebase 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 url::Origin to_origin(to_url);
Charlie Reis 2016/11/01 18:12:19 Maybe mention why this is important (for blob/file
alexmos 2016/11/01 22:04:22 Done.
521 if (to_origin.scheme() != kExtensionScheme) {
Charlie Reis 2016/11/01 18:12:19 I'm curious-- is |to_url| an effective URL or not?
alexmos 2016/11/01 22:04:22 I think |to_url| is not an effective URL. For hos
Charlie Reis 2016/11/01 23:16:27 Acknowledged.
522 // We're not responsible for protecting this resource.
523 return false;
524 }
525
504 // Do not allow pages from the web or other extensions navigate to 526 // Do not allow pages from the web or other extensions navigate to
505 // non-web-accessible extension resources. 527 // non-web-accessible extension resources.
506 if (to_url.SchemeIs(kExtensionScheme) && 528
507 (from_url.SchemeIsHTTPOrHTTPS() || from_url.SchemeIs(kExtensionScheme))) { 529 Profile* profile = Profile::FromBrowserContext(
508 Profile* profile = Profile::FromBrowserContext( 530 site_instance->GetProcess()->GetBrowserContext());
509 site_instance->GetProcess()->GetBrowserContext()); 531 ExtensionRegistry* registry = ExtensionRegistry::Get(profile);
Devlin 2016/11/02 16:19:22 Not your code, but ExtensionRegistry doesn't need
alexmos 2016/11/02 17:32:46 Done.
510 ExtensionRegistry* registry = ExtensionRegistry::Get(profile); 532 if (!registry) {
Devlin 2016/11/02 16:19:22 |registry| should never ever be null (even in test
alexmos 2016/11/02 17:32:46 Thanks, good to learn about these. :) I just remo
511 if (!registry) { 533 *result = true;
512 *result = true; 534 return true;
513 return true; 535 }
536
537 const Extension* extension =
Charlie Reis 2016/11/01 18:12:19 nit: to_extension?
alexmos 2016/11/01 22:04:22 Done.
538 registry->enabled_extensions().GetByID(to_origin.host());
Charlie Reis 2016/11/01 18:12:19 Interesting. As mentioned above, calling GetByID
alexmos 2016/11/01 22:04:22 We should never get here for hosted apps (we'd ret
539 if (!extension) {
540 *result = true;
541 return true;
542 }
543
544 GURL site_url(site_instance->GetSiteURL());
545 const Extension* from_extension =
546 registry->enabled_extensions().GetExtensionOrAppByURL(site_url);
547 if (from_extension && from_extension->id() == extension->id()) {
548 *result = true;
549 return true;
550 }
551
552 // Blob and filesystem URLs are never considered web-accessible. See
553 // https://crbug.com/656752.
554 if (to_url.SchemeIsFileSystem() || to_url.SchemeIsBlob()) {
555 if (to_url.SchemeIsFileSystem()) {
556 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure",
557 FAILURE_FILE_SYSTEM_URL, FAILURE_LAST);
558 } else {
559 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure",
560 FAILURE_BLOB_URL, FAILURE_LAST);
514 } 561 }
515 const Extension* extension = 562 // TODO(alexmos): Temporary instrumentation to find any regressions for
516 registry->enabled_extensions().GetExtensionOrAppByURL(to_url); 563 // this blocking. Remove after verifying that this is not breaking any
517 if (!extension) { 564 // legitimate use cases.
518 *result = true; 565 char site_url_copy[256];
519 return true; 566 base::strlcpy(site_url_copy, site_url.spec().c_str(),
520 } 567 arraysize(site_url_copy));
521 const Extension* from_extension = 568 base::debug::Alias(&site_url_copy);
522 registry->enabled_extensions().GetExtensionOrAppByURL( 569 char to_origin_copy[256];
523 site_instance->GetSiteURL()); 570 base::strlcpy(to_origin_copy, to_origin.Serialize().c_str(),
524 if (from_extension && from_extension->id() == extension->id()) { 571 arraysize(to_origin_copy));
525 *result = true; 572 base::debug::Alias(&to_origin_copy);
526 return true; 573 base::debug::DumpWithoutCrashing();
527 }
528 574
529 if (!WebAccessibleResourcesInfo::IsResourceWebAccessible( 575 *result = false;
530 extension, to_url.path())) { 576 return true;
531 *result = false;
532 return true;
533 }
534 } 577 }
535 return false; 578
579 if (WebAccessibleResourcesInfo::IsResourceWebAccessible(extension,
580 to_url.path())) {
581 *result = true;
582 return true;
583 }
584
585 if (!site_url.SchemeIsHTTPOrHTTPS() && !site_url.SchemeIs(kExtensionScheme)) {
586 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure",
587 FAILURE_SCHEME_NOT_HTTP_OR_HTTPS_OR_EXTENSION,
588 FAILURE_LAST);
589 // TODO(alexmos): Previous version of this function skipped the
590 // web-accessible resource checks in this case. Collect data to catch
591 // any regressions, and then remove this.
592 char site_url_copy[256];
593 base::strlcpy(site_url_copy, site_url.spec().c_str(),
594 arraysize(site_url_copy));
595 base::debug::Alias(&site_url_copy);
596 char to_origin_copy[256];
597 base::strlcpy(to_origin_copy, to_origin.Serialize().c_str(),
598 arraysize(to_origin_copy));
599 base::debug::Alias(&to_origin_copy);
600 base::debug::DumpWithoutCrashing();
601 } else {
602 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure",
603 FAILURE_RESOURCE_NOT_WEB_ACCESSIBLE,
604 FAILURE_LAST);
605 }
606
607 *result = false;
608 return true;
536 } 609 }
537 610
538 // static 611 // static
539 std::unique_ptr<content::VpnServiceProxy> 612 std::unique_ptr<content::VpnServiceProxy>
540 ChromeContentBrowserClientExtensionsPart::GetVpnServiceProxy( 613 ChromeContentBrowserClientExtensionsPart::GetVpnServiceProxy(
541 content::BrowserContext* browser_context) { 614 content::BrowserContext* browser_context) {
542 #if defined(OS_CHROMEOS) 615 #if defined(OS_CHROMEOS)
543 chromeos::VpnService* vpn_service = 616 chromeos::VpnService* vpn_service =
544 chromeos::VpnServiceFactory::GetForBrowserContext(browser_context); 617 chromeos::VpnServiceFactory::GetForBrowserContext(browser_context);
545 if (!vpn_service) 618 if (!vpn_service)
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 command_line->AppendSwitch(switches::kExtensionProcess); 760 command_line->AppendSwitch(switches::kExtensionProcess);
688 } 761 }
689 } 762 }
690 763
691 void ChromeContentBrowserClientExtensionsPart::ResourceDispatcherHostCreated() { 764 void ChromeContentBrowserClientExtensionsPart::ResourceDispatcherHostCreated() {
692 content::ResourceDispatcherHost::Get()->RegisterInterceptor( 765 content::ResourceDispatcherHost::Get()->RegisterInterceptor(
693 "Origin", kExtensionScheme, base::Bind(&OnHttpHeaderReceived)); 766 "Origin", kExtensionScheme, base::Bind(&OnHttpHeaderReceived));
694 } 767 }
695 768
696 } // namespace extensions 769 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698