diff --git a/libcef/browser/content_browser_client.cc b/libcef/browser/content_browser_client.cc index d087837d1..64f3b3c28 100644 --- a/libcef/browser/content_browser_client.cc +++ b/libcef/browser/content_browser_client.cc @@ -77,7 +77,6 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_ppapi_host.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/overlay_window.h" @@ -1481,16 +1480,6 @@ CefContentBrowserClient::GetPluginMimeTypesWithExternalHandlers( return mime_types; } -void CefContentBrowserClient::RegisterCustomScheme(const std::string& scheme) { - // Register as a Web-safe scheme so that requests for the scheme from a - // render process will be allowed in resource_dispatcher_host_impl.cc - // ShouldServiceRequest. - content::ChildProcessSecurityPolicy* policy = - content::ChildProcessSecurityPolicy::GetInstance(); - if (!policy->IsWebSafeScheme(scheme)) - policy->RegisterWebSafeScheme(scheme); -} - CefRefPtr CefContentBrowserClient::request_context() const { return browser_main_parts_->request_context(); diff --git a/libcef/browser/content_browser_client.h b/libcef/browser/content_browser_client.h index 40cfea20e..a6737919b 100644 --- a/libcef/browser/content_browser_client.h +++ b/libcef/browser/content_browser_client.h @@ -210,9 +210,6 @@ class CefContentBrowserClient : public content::ContentBrowserClient { base::flat_set GetPluginMimeTypesWithExternalHandlers( content::BrowserContext* browser_context) override; - // Perform browser process registration for the custom scheme. - void RegisterCustomScheme(const std::string& scheme); - CefRefPtr request_context() const; CefDevToolsDelegate* devtools_delegate() const; diff --git a/libcef/common/content_client.cc b/libcef/common/content_client.cc index c27b0f666..6063064f9 100644 --- a/libcef/common/content_client.cc +++ b/libcef/common/content_client.cc @@ -9,7 +9,6 @@ #include "include/cef_stream.h" #include "include/cef_version.h" -#include "libcef/browser/content_browser_client.h" #include "libcef/browser/extensions/pdf_extension_util.h" #include "libcef/common/cef_switches.h" #include "libcef/common/extensions/extensions_util.h" @@ -30,6 +29,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pepper_flash.h" +#include "content/public/browser/child_process_security_policy.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_switches.h" #include "content/public/common/pepper_plugin_info.h" @@ -292,9 +292,15 @@ void CefContentClient::AddCustomScheme(const SchemeInfo& scheme_info) { DCHECK(!scheme_info_list_locked_); scheme_info_list_.push_back(scheme_info); - if (CefContentBrowserClient::Get()) { - CefContentBrowserClient::Get()->RegisterCustomScheme( - scheme_info.scheme_name); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(switches::kProcessType)) { + // Register as a Web-safe scheme in the browser process so that requests for + // the scheme from a render process will be allowed in + // resource_dispatcher_host_impl.cc ShouldServiceRequest. + content::ChildProcessSecurityPolicy* policy = + content::ChildProcessSecurityPolicy::GetInstance(); + if (!policy->IsWebSafeScheme(scheme_info.scheme_name)) + policy->RegisterWebSafeScheme(scheme_info.scheme_name); } } diff --git a/tests/ceftests/scheme_handler_unittest.cc b/tests/ceftests/scheme_handler_unittest.cc index ff7652000..4fd4d076c 100644 --- a/tests/ceftests/scheme_handler_unittest.cc +++ b/tests/ceftests/scheme_handler_unittest.cc @@ -1401,6 +1401,91 @@ TEST(SchemeHandlerTest, CustomStandardXSSDifferentOrigin) { ClearTestSchemes(); } +// Test that a cross-protocol iframe load succeeds, and that the custom +// standard scheme cannot generate XSS requests to the HTTP protocol by default. +TEST(SchemeHandlerTest, CustomStandardXSSDifferentProtocolHttp) { + RegisterTestScheme("customstd", "test1"); + RegisterTestScheme("http", "test2"); + SetUpXSS("customstd://test1/run.html", "http://test2/iframe.html"); + + CefRefPtr handler = new TestSchemeHandler(&g_TestResults); + handler->ExecuteTest(); + ReleaseAndWaitForDestructor(handler); + + EXPECT_TRUE(g_TestResults.got_request); + EXPECT_TRUE(g_TestResults.got_read); + EXPECT_TRUE(g_TestResults.got_output); + EXPECT_TRUE(g_TestResults.got_sub_request); + EXPECT_TRUE(g_TestResults.got_sub_read); + EXPECT_FALSE(g_TestResults.got_sub_success); + + ClearTestSchemes(); +} + +// Test that a cross-protocol iframe load succeeds, and that the custom +// standard scheme cannot generate XSS requests to a non-standard scheme by +// default. +TEST(SchemeHandlerTest, CustomStandardXSSDifferentProtocolCustomNonStandard) { + RegisterTestScheme("customstd", "test1"); + RegisterTestScheme("customnonstd", std::string()); + SetUpXSS("customstd://test1/run.html", "customnonstd:some%20value"); + + CefRefPtr handler = new TestSchemeHandler(&g_TestResults); + handler->ExecuteTest(); + ReleaseAndWaitForDestructor(handler); + + EXPECT_TRUE(g_TestResults.got_request); + EXPECT_TRUE(g_TestResults.got_read); + EXPECT_TRUE(g_TestResults.got_output); + EXPECT_TRUE(g_TestResults.got_sub_request); + EXPECT_TRUE(g_TestResults.got_sub_read); + EXPECT_FALSE(g_TestResults.got_sub_success); + + ClearTestSchemes(); +} + +// Test that a cross-protocol iframe load succeeds, and that the HTTP protocol +// cannot generate XSS requests to the custom standard scheme by default. +TEST(SchemeHandlerTest, HttpXSSDifferentProtocolCustomStandard) { + RegisterTestScheme("http", "test1"); + RegisterTestScheme("customstd", "test2"); + SetUpXSS("http://test1/run.html", "customstd://test2/iframe.html"); + + CefRefPtr handler = new TestSchemeHandler(&g_TestResults); + handler->ExecuteTest(); + ReleaseAndWaitForDestructor(handler); + + EXPECT_TRUE(g_TestResults.got_request); + EXPECT_TRUE(g_TestResults.got_read); + EXPECT_TRUE(g_TestResults.got_output); + EXPECT_TRUE(g_TestResults.got_sub_request); + EXPECT_TRUE(g_TestResults.got_sub_read); + EXPECT_FALSE(g_TestResults.got_sub_success); + + ClearTestSchemes(); +} + +// Test that a cross-protocol iframe load succeeds, and that the HTTP protocol +// cannot generate XSS requests to the custom non-standard scheme by default. +TEST(SchemeHandlerTest, HttpXSSDifferentProtocolCustomNonStandard) { + RegisterTestScheme("http", "test1"); + RegisterTestScheme("customnonstd", std::string()); + SetUpXSS("http://test1/run.html", "customnonstd:some%20value"); + + CefRefPtr handler = new TestSchemeHandler(&g_TestResults); + handler->ExecuteTest(); + ReleaseAndWaitForDestructor(handler); + + EXPECT_TRUE(g_TestResults.got_request); + EXPECT_TRUE(g_TestResults.got_read); + EXPECT_TRUE(g_TestResults.got_output); + EXPECT_TRUE(g_TestResults.got_sub_request); + EXPECT_TRUE(g_TestResults.got_sub_read); + EXPECT_FALSE(g_TestResults.got_sub_success); + + ClearTestSchemes(); +} + // Test that an HTTP scheme cannot generate cross-domain XHR requests by // default. TEST(SchemeHandlerTest, HttpXHRDifferentOriginSync) {