blob: 6402e767decba4244aa92a09e79da216db3a9cf4 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/webui_config_map.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/scoped_web_ui_controller_factory_registration.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/web_ui_browsertest_util.h"
#include "ipc/ipc_security_test_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "ui/webui/untrusted_web_ui_browsertest_util.h"
#include "url/url_constants.h"
// Tests embedder specific behavior of WebUIs.
class ChromeWebUINavigationBrowserTest : public InProcessBrowserTest {
protected:
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(embedded_test_server()->Start());
}
private:
content::TestWebUIControllerFactory factory_;
content::ScopedWebUIControllerFactoryRegistration factory_registration_{
&factory_};
};
// Verify that a browser check stops websites from embeding chrome:// iframes.
// This is a copy of the DisallowEmbeddingChromeSchemeFromWebFrameBrowserCheck
// test in content/browser/webui/web_ui_navigation_browsertest.cc. We need a
// copy here because the browser side check is done by embedders.
IN_PROC_BROWSER_TEST_F(ChromeWebUINavigationBrowserTest,
DisallowEmbeddingChromeSchemeFromWebFrameBrowserCheck) {
GURL main_frame_url(embedded_test_server()->GetURL("/title1.html"));
auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));
auto* main_frame = web_contents->GetPrimaryMainFrame();
// Add iframe but don't navigate it to a chrome:// URL yet.
EXPECT_TRUE(content::ExecJs(main_frame,
"var frame = document.createElement('iframe');\n"
"document.body.appendChild(frame);\n",
content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
1 /* world_id */));
content::RenderFrameHost* child = content::ChildFrameAt(main_frame, 0);
EXPECT_EQ("about:blank", child->GetLastCommittedURL());
content::TestNavigationObserver observer(web_contents);
content::PwnMessageHelper::OpenURL(
child, content::GetWebUIURL("web-ui/title1.html?noxfo=true"));
observer.Wait();
// Retrieve the RenderFrameHost again since it might have been swapped.
child = content::ChildFrameAt(main_frame, 0);
EXPECT_EQ(content::kBlockedURL, child->GetLastCommittedURL());
}
// Verify that a browser check stops websites from embeding chrome-untrusted://
// iframes. This is a copy of the
// DisallowEmbeddingChromeUntrustedSchemeFromWebFrameBrowserCheck test in
// content/browser/webui/web_ui_navigation_browsertest.cc. We need a copy here
// because the browser side check is done by embedders.
IN_PROC_BROWSER_TEST_F(
ChromeWebUINavigationBrowserTest,
DisallowEmbeddingChromeUntrustedSchemeFromWebFrameBrowserCheck) {
GURL main_frame_url(embedded_test_server()->GetURL("/title1.html"));
auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));
auto* main_frame = web_contents->GetPrimaryMainFrame();
// Add iframe but don't navigate it to a chrome-untrusted:// URL yet.
EXPECT_TRUE(content::ExecJs(main_frame,
"var frame = document.createElement('iframe');\n"
"document.body.appendChild(frame);\n",
content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
1 /* world_id */));
content::RenderFrameHost* child = content::ChildFrameAt(main_frame, 0);
EXPECT_EQ("about:blank", child->GetLastCommittedURL());
content::TestNavigationObserver observer(web_contents);
content::TestUntrustedDataSourceHeaders headers;
headers.no_xfo = true;
content::WebUIConfigMap::GetInstance().AddUntrustedWebUIConfig(
std::make_unique<ui::TestUntrustedWebUIConfig>("test-iframe-host",
headers));
content::PwnMessageHelper::OpenURL(
child, content::GetChromeUntrustedUIURL("test-iframe-host/title1.html"));
observer.Wait();
// Retrieve the RenderFrameHost again since it might have been swapped.
child = content::ChildFrameAt(main_frame, 0);
EXPECT_EQ(content::kBlockedURL, child->GetLastCommittedURL());
}