| 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 "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 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
| 23 #include "chrome/browser/profiles/profile_io_data.h" | 23 #include "chrome/browser/profiles/profile_io_data.h" |
| 24 #include "chrome/browser/profiles/profile_manager.h" | 24 #include "chrome/browser/profiles/profile_manager.h" |
| 25 #include "chrome/browser/renderer_host/chrome_extension_message_filter.h" | 25 #include "chrome/browser/renderer_host/chrome_extension_message_filter.h" |
| 26 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" | 26 #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" |
| 27 #include "chrome/common/chrome_constants.h" | 27 #include "chrome/common/chrome_constants.h" |
| 28 #include "chrome/common/chrome_switches.h" | 28 #include "chrome/common/chrome_switches.h" |
| 29 #include "chrome/common/extensions/extension_constants.h" | 29 #include "chrome/common/extensions/extension_constants.h" |
| 30 #include "chrome/common/extensions/extension_process_policy.h" | 30 #include "chrome/common/extensions/extension_process_policy.h" |
| 31 #include "chrome/common/url_constants.h" | 31 #include "chrome/common/url_constants.h" |
| 32 #include "components/dom_distiller/core/url_constants.h" |
| 32 #include "components/guest_view/browser/guest_view_message_filter.h" | 33 #include "components/guest_view/browser/guest_view_message_filter.h" |
| 33 #include "content/public/browser/browser_thread.h" | 34 #include "content/public/browser/browser_thread.h" |
| 34 #include "content/public/browser/browser_url_handler.h" | 35 #include "content/public/browser/browser_url_handler.h" |
| 35 #include "content/public/browser/page_navigator.h" | 36 #include "content/public/browser/page_navigator.h" |
| 36 #include "content/public/browser/render_process_host.h" | 37 #include "content/public/browser/render_process_host.h" |
| 37 #include "content/public/browser/render_view_host.h" | 38 #include "content/public/browser/render_view_host.h" |
| 38 #include "content/public/browser/resource_dispatcher_host.h" | 39 #include "content/public/browser/resource_dispatcher_host.h" |
| 39 #include "content/public/browser/site_instance.h" | 40 #include "content/public/browser/site_instance.h" |
| 40 #include "content/public/browser/storage_partition.h" | 41 #include "content/public/browser/storage_partition.h" |
| 41 #include "content/public/browser/vpn_service_proxy.h" | 42 #include "content/public/browser/vpn_service_proxy.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 // below. Extension, and isolated apps require different privileges to be | 86 // below. Extension, and isolated apps require different privileges to be |
| 86 // granted to their RenderProcessHosts. This classification allows us to make | 87 // granted to their RenderProcessHosts. This classification allows us to make |
| 87 // sure URLs are served by hosts with the right set of privileges. | 88 // sure URLs are served by hosts with the right set of privileges. |
| 88 enum RenderProcessHostPrivilege { | 89 enum RenderProcessHostPrivilege { |
| 89 PRIV_NORMAL, | 90 PRIV_NORMAL, |
| 90 PRIV_HOSTED, | 91 PRIV_HOSTED, |
| 91 PRIV_ISOLATED, | 92 PRIV_ISOLATED, |
| 92 PRIV_EXTENSION, | 93 PRIV_EXTENSION, |
| 93 }; | 94 }; |
| 94 | 95 |
| 95 // Specifies reasons why web-accessible resource checks in ShouldAllowOpenURL | 96 // Specifies the scheme of the SiteInstance responsible for a failed |
| 96 // might fail. | 97 // web-accessible resource check in ShouldAllowOpenURL. |
| 97 // | 98 // |
| 98 // This enum backs an UMA histogram. The order of existing values | 99 // This enum backs an UMA histogram. The order of existing values |
| 99 // should not be changed, and new values should only be added before | 100 // should not be changed. Add any new values before SCHEME_LAST, and also run |
| 100 // FAILURE_LAST. | 101 // update_should_allow_open_url_histograms.py to update the corresponding enum |
| 101 enum ShouldAllowOpenURLFailureReason { | 102 // in histograms.xml. This enum must also be synchronized to kSchemeNames in |
| 102 FAILURE_FILE_SYSTEM_URL = 0, | 103 // RecordShouldAllowOpenURLFailure. |
| 103 FAILURE_BLOB_URL, | 104 enum ShouldAllowOpenURLFailureScheme { |
| 104 FAILURE_SCHEME_NOT_HTTP_OR_HTTPS_OR_EXTENSION, | 105 SCHEME_UNKNOWN, |
| 105 FAILURE_RESOURCE_NOT_WEB_ACCESSIBLE, | 106 SCHEME_EMPTY, |
| 106 FAILURE_LAST, | 107 SCHEME_HTTP, |
| 108 SCHEME_HTTPS, |
| 109 SCHEME_FILE, |
| 110 SCHEME_FTP, |
| 111 SCHEME_DATA, |
| 112 SCHEME_JAVASCRIPT, |
| 113 SCHEME_ABOUT, |
| 114 SCHEME_CHROME, |
| 115 SCHEME_DEVTOOLS, |
| 116 SCHEME_GUEST, |
| 117 SCHEME_VIEWSOURCE, |
| 118 SCHEME_CHROME_SEARCH, |
| 119 SCHEME_CHROME_NATIVE, |
| 120 SCHEME_DOM_DISTILLER, |
| 121 SCHEME_CHROME_EXTENSION, |
| 122 SCHEME_CONTENT, |
| 123 SCHEME_BLOB, |
| 124 SCHEME_FILESYSTEM, |
| 125 // Add new entries above and make sure to update histograms.xml by running |
| 126 // update_should_allow_open_url_histograms.py. |
| 127 SCHEME_LAST, |
| 107 }; | 128 }; |
| 108 | 129 |
| 109 RenderProcessHostPrivilege GetPrivilegeRequiredByUrl( | 130 RenderProcessHostPrivilege GetPrivilegeRequiredByUrl( |
| 110 const GURL& url, | 131 const GURL& url, |
| 111 ExtensionRegistry* registry) { | 132 ExtensionRegistry* registry) { |
| 112 // Default to a normal renderer cause it is lower privileged. This should only | 133 // Default to a normal renderer cause it is lower privileged. This should only |
| 113 // occur if the URL on a site instance is either malformed, or uninitialized. | 134 // occur if the URL on a site instance is either malformed, or uninitialized. |
| 114 // If it is malformed, then there is no need for better privileges anyways. | 135 // If it is malformed, then there is no need for better privileges anyways. |
| 115 // If it is uninitialized, but eventually settles on being an a scheme other | 136 // If it is uninitialized, but eventually settles on being an a scheme other |
| 116 // than normal webrenderer, the navigation logic will correct us out of band | 137 // than normal webrenderer, the navigation logic will correct us out of band |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 content::ResourceContext* resource_context, | 242 content::ResourceContext* resource_context, |
| 222 content::OnHeaderProcessedCallback callback) { | 243 content::OnHeaderProcessedCallback callback) { |
| 223 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 244 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 224 | 245 |
| 225 GURL origin(value); | 246 GURL origin(value); |
| 226 DCHECK(origin.SchemeIs(extensions::kExtensionScheme)); | 247 DCHECK(origin.SchemeIs(extensions::kExtensionScheme)); |
| 227 | 248 |
| 228 callback.Run(CheckOriginHeader(resource_context, child_id, origin)); | 249 callback.Run(CheckOriginHeader(resource_context, child_id, origin)); |
| 229 } | 250 } |
| 230 | 251 |
| 231 void RecordShowAllowOpenURLFailure(ShouldAllowOpenURLFailureReason reason) { | |
| 232 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure", reason, | |
| 233 FAILURE_LAST); | |
| 234 } | |
| 235 | |
| 236 } // namespace | 252 } // namespace |
| 237 | 253 |
| 238 ChromeContentBrowserClientExtensionsPart:: | 254 ChromeContentBrowserClientExtensionsPart:: |
| 239 ChromeContentBrowserClientExtensionsPart() { | 255 ChromeContentBrowserClientExtensionsPart() { |
| 240 } | 256 } |
| 241 | 257 |
| 242 ChromeContentBrowserClientExtensionsPart:: | 258 ChromeContentBrowserClientExtensionsPart:: |
| 243 ~ChromeContentBrowserClientExtensionsPart() { | 259 ~ChromeContentBrowserClientExtensionsPart() { |
| 244 } | 260 } |
| 245 | 261 |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 registry->enabled_extensions().GetExtensionOrAppByURL(site_url); | 596 registry->enabled_extensions().GetExtensionOrAppByURL(site_url); |
| 581 if (from_extension && from_extension == to_extension) { | 597 if (from_extension && from_extension == to_extension) { |
| 582 *result = true; | 598 *result = true; |
| 583 return true; | 599 return true; |
| 584 } | 600 } |
| 585 | 601 |
| 586 // Blob and filesystem URLs are never considered web-accessible. See | 602 // Blob and filesystem URLs are never considered web-accessible. See |
| 587 // https://crbug.com/656752. | 603 // https://crbug.com/656752. |
| 588 if (to_url.SchemeIsFileSystem() || to_url.SchemeIsBlob()) { | 604 if (to_url.SchemeIsFileSystem() || to_url.SchemeIsBlob()) { |
| 589 if (to_url.SchemeIsFileSystem()) | 605 if (to_url.SchemeIsFileSystem()) |
| 590 RecordShowAllowOpenURLFailure(FAILURE_FILE_SYSTEM_URL); | 606 RecordShouldAllowOpenURLFailure(FAILURE_FILE_SYSTEM_URL, site_url); |
| 591 else | 607 else |
| 592 RecordShowAllowOpenURLFailure(FAILURE_BLOB_URL); | 608 RecordShouldAllowOpenURLFailure(FAILURE_BLOB_URL, site_url); |
| 593 | 609 |
| 594 // TODO(alexmos): Temporary instrumentation to find any regressions for | 610 // TODO(alexmos): Temporary instrumentation to find any regressions for |
| 595 // this blocking. Remove after verifying that this is not breaking any | 611 // this blocking. Remove after verifying that this is not breaking any |
| 596 // legitimate use cases. | 612 // legitimate use cases. |
| 597 char site_url_copy[256]; | 613 char site_url_copy[256]; |
| 598 base::strlcpy(site_url_copy, site_url.spec().c_str(), | 614 base::strlcpy(site_url_copy, site_url.spec().c_str(), |
| 599 arraysize(site_url_copy)); | 615 arraysize(site_url_copy)); |
| 600 base::debug::Alias(&site_url_copy); | 616 base::debug::Alias(&site_url_copy); |
| 601 char to_origin_copy[256]; | 617 char to_origin_copy[256]; |
| 602 base::strlcpy(to_origin_copy, to_origin.Serialize().c_str(), | 618 base::strlcpy(to_origin_copy, to_origin.Serialize().c_str(), |
| (...skipping 27 matching lines...) Expand all Loading... |
| 630 return true; | 646 return true; |
| 631 } | 647 } |
| 632 | 648 |
| 633 if (WebAccessibleResourcesInfo::IsResourceWebAccessible(to_extension, | 649 if (WebAccessibleResourcesInfo::IsResourceWebAccessible(to_extension, |
| 634 to_url.path())) { | 650 to_url.path())) { |
| 635 *result = true; | 651 *result = true; |
| 636 return true; | 652 return true; |
| 637 } | 653 } |
| 638 | 654 |
| 639 if (!site_url.SchemeIsHTTPOrHTTPS() && !site_url.SchemeIs(kExtensionScheme)) { | 655 if (!site_url.SchemeIsHTTPOrHTTPS() && !site_url.SchemeIs(kExtensionScheme)) { |
| 640 RecordShowAllowOpenURLFailure( | 656 // This function used to incorrectly skip the web-accessible resource |
| 641 FAILURE_SCHEME_NOT_HTTP_OR_HTTPS_OR_EXTENSION); | 657 // checks in this case. Measure how often this happens. See also |
| 642 | 658 // https://crbug.com/696034. |
| 643 // TODO(alexmos): Previous version of this function skipped the | 659 RecordShouldAllowOpenURLFailure( |
| 644 // web-accessible resource checks in this case. Collect data to catch | 660 FAILURE_SCHEME_NOT_HTTP_OR_HTTPS_OR_EXTENSION, site_url); |
| 645 // any regressions, and then remove this. | |
| 646 char site_url_copy[256]; | |
| 647 base::strlcpy(site_url_copy, site_url.spec().c_str(), | |
| 648 arraysize(site_url_copy)); | |
| 649 base::debug::Alias(&site_url_copy); | |
| 650 char to_origin_copy[256]; | |
| 651 base::strlcpy(to_origin_copy, to_origin.Serialize().c_str(), | |
| 652 arraysize(to_origin_copy)); | |
| 653 base::debug::Alias(&to_origin_copy); | |
| 654 base::debug::DumpWithoutCrashing(); | |
| 655 } else { | 661 } else { |
| 656 RecordShowAllowOpenURLFailure(FAILURE_RESOURCE_NOT_WEB_ACCESSIBLE); | 662 RecordShouldAllowOpenURLFailure(FAILURE_RESOURCE_NOT_WEB_ACCESSIBLE, |
| 663 site_url); |
| 657 } | 664 } |
| 658 | 665 |
| 659 *result = false; | 666 *result = false; |
| 660 return true; | 667 return true; |
| 661 } | 668 } |
| 662 | 669 |
| 663 // static | 670 // static |
| 664 std::unique_ptr<content::VpnServiceProxy> | 671 std::unique_ptr<content::VpnServiceProxy> |
| 665 ChromeContentBrowserClientExtensionsPart::GetVpnServiceProxy( | 672 ChromeContentBrowserClientExtensionsPart::GetVpnServiceProxy( |
| 666 content::BrowserContext* browser_context) { | 673 content::BrowserContext* browser_context) { |
| 667 #if defined(OS_CHROMEOS) | 674 #if defined(OS_CHROMEOS) |
| 668 chromeos::VpnService* vpn_service = | 675 chromeos::VpnService* vpn_service = |
| 669 chromeos::VpnServiceFactory::GetForBrowserContext(browser_context); | 676 chromeos::VpnServiceFactory::GetForBrowserContext(browser_context); |
| 670 if (!vpn_service) | 677 if (!vpn_service) |
| 671 return nullptr; | 678 return nullptr; |
| 672 return vpn_service->GetVpnServiceProxy(); | 679 return vpn_service->GetVpnServiceProxy(); |
| 673 #else | 680 #else |
| 674 return nullptr; | 681 return nullptr; |
| 675 #endif | 682 #endif |
| 676 } | 683 } |
| 677 | 684 |
| 685 // static |
| 686 void ChromeContentBrowserClientExtensionsPart::RecordShouldAllowOpenURLFailure( |
| 687 ShouldAllowOpenURLFailureReason reason, |
| 688 const GURL& site_url) { |
| 689 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure", reason, |
| 690 FAILURE_LAST); |
| 691 |
| 692 // Must be kept in sync with the ShouldAllowOpenURLFailureScheme enum. |
| 693 static const char* const kSchemeNames[] = { |
| 694 "unknown", |
| 695 "", |
| 696 url::kHttpScheme, |
| 697 url::kHttpsScheme, |
| 698 url::kFileScheme, |
| 699 url::kFtpScheme, |
| 700 url::kDataScheme, |
| 701 url::kJavaScriptScheme, |
| 702 url::kAboutScheme, |
| 703 content::kChromeUIScheme, |
| 704 content::kChromeDevToolsScheme, |
| 705 content::kGuestScheme, |
| 706 content::kViewSourceScheme, |
| 707 chrome::kChromeSearchScheme, |
| 708 chrome::kChromeNativeScheme, |
| 709 dom_distiller::kDomDistillerScheme, |
| 710 extensions::kExtensionScheme, |
| 711 url::kContentScheme, |
| 712 url::kBlobScheme, |
| 713 url::kFileSystemScheme, |
| 714 "last", |
| 715 }; |
| 716 |
| 717 static_assert(arraysize(kSchemeNames) == SCHEME_LAST + 1, |
| 718 "kSchemeNames should have SCHEME_LAST + 1 elements"); |
| 719 |
| 720 ShouldAllowOpenURLFailureScheme scheme = SCHEME_UNKNOWN; |
| 721 for (int i = 1; i < SCHEME_LAST; i++) { |
| 722 if (site_url.SchemeIs(kSchemeNames[i])) { |
| 723 scheme = static_cast<ShouldAllowOpenURLFailureScheme>(i); |
| 724 break; |
| 725 } |
| 726 } |
| 727 |
| 728 UMA_HISTOGRAM_ENUMERATION("Extensions.ShouldAllowOpenURL.Failure.Scheme", |
| 729 scheme, SCHEME_LAST); |
| 730 } |
| 731 |
| 678 void ChromeContentBrowserClientExtensionsPart::RenderProcessWillLaunch( | 732 void ChromeContentBrowserClientExtensionsPart::RenderProcessWillLaunch( |
| 679 content::RenderProcessHost* host) { | 733 content::RenderProcessHost* host) { |
| 680 int id = host->GetID(); | 734 int id = host->GetID(); |
| 681 Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext()); | 735 Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext()); |
| 682 | 736 |
| 683 host->AddFilter(new ChromeExtensionMessageFilter(id, profile)); | 737 host->AddFilter(new ChromeExtensionMessageFilter(id, profile)); |
| 684 host->AddFilter(new ExtensionMessageFilter(id, profile)); | 738 host->AddFilter(new ExtensionMessageFilter(id, profile)); |
| 685 host->AddFilter(new IOThreadExtensionMessageFilter(id, profile)); | 739 host->AddFilter(new IOThreadExtensionMessageFilter(id, profile)); |
| 686 host->AddFilter(new ExtensionsGuestViewMessageFilter(id, profile)); | 740 host->AddFilter(new ExtensionsGuestViewMessageFilter(id, profile)); |
| 687 if (extensions::ExtensionsClient::Get() | 741 if (extensions::ExtensionsClient::Get() |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 command_line->AppendSwitch(switches::kExtensionProcess); | 867 command_line->AppendSwitch(switches::kExtensionProcess); |
| 814 } | 868 } |
| 815 } | 869 } |
| 816 | 870 |
| 817 void ChromeContentBrowserClientExtensionsPart::ResourceDispatcherHostCreated() { | 871 void ChromeContentBrowserClientExtensionsPart::ResourceDispatcherHostCreated() { |
| 818 content::ResourceDispatcherHost::Get()->RegisterInterceptor( | 872 content::ResourceDispatcherHost::Get()->RegisterInterceptor( |
| 819 "Origin", kExtensionScheme, base::Bind(&OnHttpHeaderReceived)); | 873 "Origin", kExtensionScheme, base::Bind(&OnHttpHeaderReceived)); |
| 820 } | 874 } |
| 821 | 875 |
| 822 } // namespace extensions | 876 } // namespace extensions |
| OLD | NEW |