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 |