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

Side by Side Diff: chrome/browser/chrome_content_browser_client.cc

Issue 2821473002: Service CreateNewWindow on the UI thread with a new mojo interface (Closed)
Patch Set: dcheng fixes + security exploit browsertest nerfing Created 3 years, 8 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/chrome_content_browser_client.h" 5 #include "chrome/browser/chrome_content_browser_client.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 772
773 return -1; 773 return -1;
774 } 774 }
775 #endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) 775 #endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
776 776
777 void SetApplicationLocaleOnIOThread(const std::string& locale) { 777 void SetApplicationLocaleOnIOThread(const std::string& locale) {
778 DCHECK_CURRENTLY_ON(BrowserThread::IO); 778 DCHECK_CURRENTLY_ON(BrowserThread::IO);
779 g_io_thread_application_locale.Get() = locale; 779 g_io_thread_application_locale.Get() = locale;
780 } 780 }
781 781
782 void HandleBlockedPopupOnUIThread(const BlockedWindowParams& params) { 782 void HandleBlockedPopupOnUIThread(const BlockedWindowParams& params,
783 RenderFrameHost* render_frame_host = RenderFrameHost::FromID( 783 RenderFrameHost* opener,
784 params.render_process_id(), params.opener_render_frame_id()); 784 WebContents* tab) {
785 if (!render_frame_host) 785 DCHECK(tab);
786 return; 786 DCHECK(opener);
787 WebContents* tab = WebContents::FromRenderFrameHost(render_frame_host);
788 // The tab might already have navigated away. We only need to do this check 787 // The tab might already have navigated away. We only need to do this check
789 // for main frames, since the RenderFrameHost for a subframe opener will have 788 // for main frames, since the RenderFrameHost for a subframe opener will have
790 // already been deleted if the main frame navigates away. 789 // already been deleted if the main frame navigates away.
ncarter (slow) 2017/04/20 21:30:36 If you add the "frame_tree_node_->current_frame_ho
Charlie Harrison 2017/04/21 15:30:07 Done.
791 if (!tab || 790 if (!opener->GetParent() && tab->GetMainFrame() != opener)
792 (!render_frame_host->GetParent() &&
793 tab->GetMainFrame() != render_frame_host))
794 return; 791 return;
795
796 prerender::PrerenderContents* prerender_contents = 792 prerender::PrerenderContents* prerender_contents =
797 prerender::PrerenderContents::FromWebContents(tab); 793 prerender::PrerenderContents::FromWebContents(tab);
798 if (prerender_contents) { 794 if (prerender_contents) {
799 prerender_contents->Destroy(prerender::FINAL_STATUS_CREATE_NEW_WINDOW); 795 prerender_contents->Destroy(prerender::FINAL_STATUS_CREATE_NEW_WINDOW);
800 return; 796 return;
801 } 797 }
802 798
803 PopupBlockerTabHelper* popup_helper = 799 PopupBlockerTabHelper* popup_helper =
804 PopupBlockerTabHelper::FromWebContents(tab); 800 PopupBlockerTabHelper::FromWebContents(tab);
805 if (!popup_helper) 801 if (!popup_helper)
806 return; 802 return;
807 popup_helper->AddBlockedPopup(params); 803 popup_helper->AddBlockedPopup(params);
808 } 804 }
809 805
810 #if BUILDFLAG(ENABLE_PLUGINS)
811 void HandleFlashDownloadActionOnUIThread(int render_process_id,
812 int render_frame_id,
813 const GURL& source_url) {
814 DCHECK_CURRENTLY_ON(BrowserThread::UI);
815 RenderFrameHost* render_frame_host =
816 RenderFrameHost::FromID(render_process_id, render_frame_id);
817 if (!render_frame_host)
818 return;
819 WebContents* web_contents =
820 WebContents::FromRenderFrameHost(render_frame_host);
821 FlashDownloadInterception::InterceptFlashDownloadNavigation(web_contents,
822 source_url);
823 }
824 #endif // BUILDFLAG(ENABLE_PLUGINS)
825
826 // An implementation of the SSLCertReporter interface used by 806 // An implementation of the SSLCertReporter interface used by
827 // SSLErrorHandler. Uses CertificateReportingService to send reports. The 807 // SSLErrorHandler. Uses CertificateReportingService to send reports. The
828 // service handles queueing and re-sending of failed reports. Each certificate 808 // service handles queueing and re-sending of failed reports. Each certificate
829 // error creates a new instance of this class. 809 // error creates a new instance of this class.
830 class CertificateReportingServiceCertReporter : public SSLCertReporter { 810 class CertificateReportingServiceCertReporter : public SSLCertReporter {
831 public: 811 public:
832 explicit CertificateReportingServiceCertReporter( 812 explicit CertificateReportingServiceCertReporter(
833 CertificateReportingService* service) 813 CertificateReportingService* service)
834 : service_(service) {} 814 : service_(service) {}
835 ~CertificateReportingServiceCertReporter() override {} 815 ~CertificateReportingServiceCertReporter() override {}
(...skipping 23 matching lines...) Expand all
859 return kMinFSM; 839 return kMinFSM;
860 if (minWidth >= kWidthForMaxFSM) 840 if (minWidth >= kWidthForMaxFSM)
861 return kMaxFSM; 841 return kMaxFSM;
862 842
863 // The font scale multiplier varies linearly between kMinFSM and kMaxFSM. 843 // The font scale multiplier varies linearly between kMinFSM and kMaxFSM.
864 float ratio = static_cast<float>(minWidth - kWidthForMinFSM) / 844 float ratio = static_cast<float>(minWidth - kWidthForMinFSM) /
865 (kWidthForMaxFSM - kWidthForMinFSM); 845 (kWidthForMaxFSM - kWidthForMinFSM);
866 return ratio * (kMaxFSM - kMinFSM) + kMinFSM; 846 return ratio * (kMaxFSM - kMinFSM) + kMinFSM;
867 } 847 }
868 848
869 void HandleSingleTabModeBlockOnUIThread(const BlockedWindowParams& params) {
870 WebContents* web_contents = tab_util::GetWebContentsByFrameID(
871 params.render_process_id(), params.opener_render_frame_id());
872 if (!web_contents)
873 return;
874
875 SingleTabModeTabHelper::FromWebContents(web_contents)->HandleOpenUrl(params);
876 }
877 #endif // defined(OS_ANDROID) 849 #endif // defined(OS_ANDROID)
878 850
879 #if BUILDFLAG(ENABLE_EXTENSIONS) 851 #if BUILDFLAG(ENABLE_EXTENSIONS)
880 // By default, JavaScript, images and autoplay are enabled in guest content. 852 // By default, JavaScript, images and autoplay are enabled in guest content.
881 void GetGuestViewDefaultContentSettingRules( 853 void GetGuestViewDefaultContentSettingRules(
882 bool incognito, 854 bool incognito,
883 RendererContentSettingRules* rules) { 855 RendererContentSettingRules* rules) {
884 rules->image_rules.push_back( 856 rules->image_rules.push_back(
885 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(), 857 ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
886 ContentSettingsPattern::Wildcard(), 858 ContentSettingsPattern::Wildcard(),
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 base::Closure callback_; 964 base::Closure callback_;
993 int count_; 965 int count_;
994 }; 966 };
995 967
996 WebContents* GetWebContents(int render_process_id, int render_frame_id) { 968 WebContents* GetWebContents(int render_process_id, int render_frame_id) {
997 RenderFrameHost* rfh = 969 RenderFrameHost* rfh =
998 RenderFrameHost::FromID(render_process_id, render_frame_id); 970 RenderFrameHost::FromID(render_process_id, render_frame_id);
999 return WebContents::FromRenderFrameHost(rfh); 971 return WebContents::FromRenderFrameHost(rfh);
1000 } 972 }
1001 973
974 #if BUILDFLAG(ENABLE_EXTENSIONS)
975 // Returns true if there is is an extension with the same origin as
976 // |source_origin| in |opener_render_process_id| with
977 // APIPermission::kBackground.
978 bool SecurityOriginHasExtensionBackgroundPermission(
979 extensions::ProcessMap* process_map,
980 extensions::ExtensionRegistry* registry,
981 const GURL& source_origin,
982 int opener_render_process_id) {
983 // Note: includes web URLs that are part of an extension's web extent.
984 const Extension* extension =
985 registry->enabled_extensions().GetExtensionOrAppByURL(source_origin);
986 return extension &&
987 extension->permissions_data()->HasAPIPermission(
988 APIPermission::kBackground) &&
989 process_map->Contains(extension->id(), opener_render_process_id);
990 }
991 #endif
992
1002 } // namespace 993 } // namespace
1003 994
1004 ChromeContentBrowserClient::ChromeContentBrowserClient() 995 ChromeContentBrowserClient::ChromeContentBrowserClient()
1005 : weak_factory_(this) { 996 : weak_factory_(this) {
1006 #if BUILDFLAG(ENABLE_PLUGINS) 997 #if BUILDFLAG(ENABLE_PLUGINS)
1007 for (size_t i = 0; i < arraysize(kPredefinedAllowedDevChannelOrigins); ++i) 998 for (size_t i = 0; i < arraysize(kPredefinedAllowedDevChannelOrigins); ++i)
1008 allowed_dev_channel_origins_.insert(kPredefinedAllowedDevChannelOrigins[i]); 999 allowed_dev_channel_origins_.insert(kPredefinedAllowedDevChannelOrigins[i]);
1009 for (size_t i = 0; i < arraysize(kPredefinedAllowedFileHandleOrigins); ++i) 1000 for (size_t i = 0; i < arraysize(kPredefinedAllowedFileHandleOrigins); ++i)
1010 allowed_file_handle_origins_.insert(kPredefinedAllowedFileHandleOrigins[i]); 1001 allowed_file_handle_origins_.insert(kPredefinedAllowedFileHandleOrigins[i]);
1011 for (size_t i = 0; i < arraysize(kPredefinedAllowedSocketOrigins); ++i) 1002 for (size_t i = 0; i < arraysize(kPredefinedAllowedSocketOrigins); ++i)
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 content::MediaObserver* ChromeContentBrowserClient::GetMediaObserver() { 2442 content::MediaObserver* ChromeContentBrowserClient::GetMediaObserver() {
2452 return MediaCaptureDevicesDispatcher::GetInstance(); 2443 return MediaCaptureDevicesDispatcher::GetInstance();
2453 } 2444 }
2454 2445
2455 content::PlatformNotificationService* 2446 content::PlatformNotificationService*
2456 ChromeContentBrowserClient::GetPlatformNotificationService() { 2447 ChromeContentBrowserClient::GetPlatformNotificationService() {
2457 return PlatformNotificationServiceImpl::GetInstance(); 2448 return PlatformNotificationServiceImpl::GetInstance();
2458 } 2449 }
2459 2450
2460 bool ChromeContentBrowserClient::CanCreateWindow( 2451 bool ChromeContentBrowserClient::CanCreateWindow(
2461 int opener_render_process_id, 2452 RenderFrameHost* opener,
2462 int opener_render_frame_id,
2463 const GURL& opener_url, 2453 const GURL& opener_url,
2464 const GURL& opener_top_level_frame_url, 2454 const GURL& opener_top_level_frame_url,
2465 const GURL& source_origin, 2455 const GURL& source_origin,
2466 content::mojom::WindowContainerType container_type, 2456 content::mojom::WindowContainerType container_type,
2467 const GURL& target_url, 2457 const GURL& target_url,
2468 const content::Referrer& referrer, 2458 const content::Referrer& referrer,
2469 const std::string& frame_name, 2459 const std::string& frame_name,
2470 WindowOpenDisposition disposition, 2460 WindowOpenDisposition disposition,
2471 const blink::mojom::WindowFeatures& features, 2461 const blink::mojom::WindowFeatures& features,
2472 bool user_gesture, 2462 bool user_gesture,
2473 bool opener_suppressed, 2463 bool opener_suppressed,
2474 content::ResourceContext* context,
2475 bool* no_javascript_access) { 2464 bool* no_javascript_access) {
2476 DCHECK_CURRENTLY_ON(BrowserThread::IO); 2465 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2466 DCHECK(opener);
2477 2467
2468 content::WebContents* web_contents =
2469 content::WebContents::FromRenderFrameHost(opener);
2470 Profile* profile =
2471 Profile::FromBrowserContext(web_contents->GetBrowserContext());
2472 DCHECK(profile);
2478 *no_javascript_access = false; 2473 *no_javascript_access = false;
2479 2474
2480 // If the opener is trying to create a background window but doesn't have 2475 // If the opener is trying to create a background window but doesn't have
2481 // the appropriate permission, fail the attempt. 2476 // the appropriate permission, fail the attempt.
2482 if (container_type == content::mojom::WindowContainerType::BACKGROUND) { 2477 if (container_type == content::mojom::WindowContainerType::BACKGROUND) {
2483 #if BUILDFLAG(ENABLE_EXTENSIONS) 2478 #if BUILDFLAG(ENABLE_EXTENSIONS)
2484 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context); 2479 auto* process_map = extensions::ProcessMap::Get(profile);
2485 InfoMap* map = io_data->GetExtensionInfoMap(); 2480 auto* registry = extensions::ExtensionRegistry::Get(profile);
2486 if (!map->SecurityOriginHasAPIPermission(source_origin, 2481 if (!SecurityOriginHasExtensionBackgroundPermission(
2487 opener_render_process_id, 2482 process_map, registry, source_origin,
2488 APIPermission::kBackground)) { 2483 opener->GetProcess()->GetID())) {
2489 return false; 2484 return false;
2490 } 2485 }
2491 2486
2492 // Note: this use of GetExtensionOrAppByURL is safe but imperfect. It may 2487 // Note: this use of GetExtensionOrAppByURL is safe but imperfect. It may
2493 // return a recently installed Extension even if this CanCreateWindow call 2488 // return a recently installed Extension even if this CanCreateWindow call
2494 // was made by an old copy of the page in a normal web process. That's ok, 2489 // was made by an old copy of the page in a normal web process. That's ok,
2495 // because the permission check above would have caused an early return 2490 // because the permission check above would have caused an early return
2496 // already. We must use the full URL to find hosted apps, though, and not 2491 // already. We must use the full URL to find hosted apps, though, and not
2497 // just the origin. 2492 // just the origin.
2498 const Extension* extension = 2493 const Extension* extension =
2499 map->extensions().GetExtensionOrAppByURL(opener_url); 2494 registry->enabled_extensions().GetExtensionOrAppByURL(opener_url);
2500 if (extension && !extensions::BackgroundInfo::AllowJSAccess(extension)) 2495 if (extension && !extensions::BackgroundInfo::AllowJSAccess(extension))
ncarter (slow) 2017/04/20 21:30:36 Hah. It would appear that an extension can sideste
Charlie Harrison 2017/04/21 15:30:07 Can you explain this a bit more? I'm happy to file
ncarter (slow) 2017/04/21 20:42:13 I filed my thoughts as crbug.com/714251
2501 *no_javascript_access = true; 2496 *no_javascript_access = true;
2502 #endif 2497 #endif
2503 2498
2504 return true; 2499 return true;
2505 } 2500 }
2506 2501
2507 #if BUILDFLAG(ENABLE_EXTENSIONS) 2502 #if BUILDFLAG(ENABLE_EXTENSIONS)
2508 if (extensions::WebViewRendererState::GetInstance()->IsGuest( 2503 if (extensions::WebViewRendererState::GetInstance()->IsGuest(
2509 opener_render_process_id)) { 2504 opener->GetProcess()->GetID())) {
2510 return true; 2505 return true;
2511 } 2506 }
2512 2507
2513 if (target_url.SchemeIs(extensions::kExtensionScheme)) { 2508 if (target_url.SchemeIs(extensions::kExtensionScheme)) {
2514 // Intentionally duplicating |io_data| and |map| code from above because we 2509 // Intentionally duplicating |registry| code from above because we want to
2515 // want to reduce calls to retrieve them as this function is a SYNC IPC 2510 // reduce calls to retrieve them as this function is a SYNC IPC handler.
2516 // handler. 2511 auto* registry = extensions::ExtensionRegistry::Get(profile);
2517 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
2518 InfoMap* map = io_data->GetExtensionInfoMap();
2519 const Extension* extension = 2512 const Extension* extension =
2520 map->extensions().GetExtensionOrAppByURL(target_url); 2513 registry->enabled_extensions().GetExtensionOrAppByURL(target_url);
2521 if (extension && extension->is_platform_app()) { 2514 if (extension && extension->is_platform_app()) {
2522 UMA_HISTOGRAM_ENUMERATION( 2515 UMA_HISTOGRAM_ENUMERATION(
2523 "Extensions.AppLoadedInTab", 2516 "Extensions.AppLoadedInTab",
2524 ClassifyAppLoadedInTabSource(opener_url, extension), 2517 ClassifyAppLoadedInTabSource(opener_url, extension),
2525 APP_LOADED_IN_TAB_SOURCE_MAX); 2518 APP_LOADED_IN_TAB_SOURCE_MAX);
2526 2519
2527 // window.open() may not be used to load v2 apps in a regular tab. 2520 // window.open() may not be used to load v2 apps in a regular tab.
2528 return false; 2521 return false;
2529 } 2522 }
2530 } 2523 }
2531 #endif 2524 #endif
2532 2525
2533 HostContentSettingsMap* content_settings = 2526 HostContentSettingsMap* content_settings =
2534 ProfileIOData::FromResourceContext(context)->GetHostContentSettingsMap(); 2527 HostContentSettingsMapFactory::GetForProfile(profile);
2535 2528
2536 #if BUILDFLAG(ENABLE_PLUGINS) 2529 #if BUILDFLAG(ENABLE_PLUGINS)
2537 if (FlashDownloadInterception::ShouldStopFlashDownloadAction( 2530 if (FlashDownloadInterception::ShouldStopFlashDownloadAction(
2538 content_settings, opener_top_level_frame_url, target_url, 2531 content_settings, opener_top_level_frame_url, target_url,
2539 user_gesture)) { 2532 user_gesture)) {
2540 BrowserThread::PostTask( 2533 FlashDownloadInterception::InterceptFlashDownloadNavigation(
2541 BrowserThread::UI, FROM_HERE, 2534 web_contents, opener_top_level_frame_url);
2542 base::BindOnce(&HandleFlashDownloadActionOnUIThread,
2543 opener_render_process_id, opener_render_frame_id,
2544 opener_top_level_frame_url));
2545 return false; 2535 return false;
2546 } 2536 }
2547 #endif 2537 #endif
2548 2538
2549 BlockedWindowParams blocked_params(
2550 target_url, referrer, frame_name, disposition, features, user_gesture,
2551 opener_suppressed, opener_render_process_id, opener_render_frame_id);
2552
2553 if (!user_gesture && 2539 if (!user_gesture &&
2554 !base::CommandLine::ForCurrentProcess()->HasSwitch( 2540 !base::CommandLine::ForCurrentProcess()->HasSwitch(
2555 switches::kDisablePopupBlocking)) { 2541 switches::kDisablePopupBlocking)) {
2556 if (content_settings->GetContentSetting(opener_top_level_frame_url, 2542 if (content_settings->GetContentSetting(
2557 opener_top_level_frame_url, 2543 opener_top_level_frame_url, opener_top_level_frame_url,
2558 CONTENT_SETTINGS_TYPE_POPUPS, 2544 CONTENT_SETTINGS_TYPE_POPUPS,
2559 std::string()) != 2545 std::string()) != CONTENT_SETTING_ALLOW) {
2560 CONTENT_SETTING_ALLOW) { 2546 BlockedWindowParams blocked_params(target_url, referrer, frame_name,
2561 BrowserThread::PostTask( 2547 disposition, features, user_gesture,
2562 BrowserThread::UI, FROM_HERE, 2548 opener_suppressed);
2563 base::BindOnce(&HandleBlockedPopupOnUIThread, blocked_params)); 2549 HandleBlockedPopupOnUIThread(blocked_params, opener, web_contents);
2564 return false; 2550 return false;
2565 } 2551 }
2566 } 2552 }
2567 2553
2568 #if defined(OS_ANDROID) 2554 #if defined(OS_ANDROID)
2569 if (SingleTabModeTabHelper::IsRegistered(opener_render_process_id, 2555 auto* single_tab_mode_helper =
2570 opener_render_frame_id)) { 2556 SingleTabModeTabHelper::FromWebContents(web_contents);
2571 BrowserThread::PostTask(BrowserThread::UI, 2557 if (single_tab_mode_helper->block_all_new_windows()) {
2572 FROM_HERE, 2558 BlockedWindowParams blocked_params(target_url, referrer, frame_name,
2573 base::Bind(&HandleSingleTabModeBlockOnUIThread, 2559 disposition, features, user_gesture,
2574 blocked_params)); 2560 opener_suppressed);
2561 single_tab_mode_helper->HandleOpenUrl(blocked_params);
2575 return false; 2562 return false;
2576 } 2563 }
2577 #endif 2564 #endif
2578 2565
2579 return true; 2566 return true;
2580 } 2567 }
2581 2568
2582 void ChromeContentBrowserClient::ResourceDispatcherHostCreated() { 2569 void ChromeContentBrowserClient::ResourceDispatcherHostCreated() {
2583 DCHECK_CURRENTLY_ON(BrowserThread::UI); 2570 DCHECK_CURRENTLY_ON(BrowserThread::UI);
2584 for (size_t i = 0; i < extra_parts_.size(); ++i) 2571 for (size_t i = 0; i < extra_parts_.size(); ++i)
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after
3640 RedirectNonUINonIOBrowserThreadsToTaskScheduler() { 3627 RedirectNonUINonIOBrowserThreadsToTaskScheduler() {
3641 return variations::GetVariationParamValue( 3628 return variations::GetVariationParamValue(
3642 "BrowserScheduler", "RedirectNonUINonIOBrowserThreads") == "true"; 3629 "BrowserScheduler", "RedirectNonUINonIOBrowserThreads") == "true";
3643 } 3630 }
3644 3631
3645 // static 3632 // static
3646 void ChromeContentBrowserClient::SetDefaultQuotaSettingsForTesting( 3633 void ChromeContentBrowserClient::SetDefaultQuotaSettingsForTesting(
3647 const storage::QuotaSettings* settings) { 3634 const storage::QuotaSettings* settings) {
3648 g_default_quota_settings = settings; 3635 g_default_quota_settings = settings;
3649 } 3636 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698