Skip to content

Commit

Permalink
Merge pull request #13268 from brave/block-3p-iframe-provider
Browse files Browse the repository at this point in the history
Prevent brave wallet providers from being generated in third party iframe
  • Loading branch information
darkdh authored May 10, 2022
2 parents 02e9e60 + 75f935c commit 92462c7
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 18 deletions.
59 changes: 48 additions & 11 deletions browser/brave_wallet/solana_provider_renderer_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "content/public/common/content_client.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_mock_cert_verifier.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
Expand Down Expand Up @@ -440,22 +441,37 @@ class SolanaProviderRendererTest : public InProcessBrowserTest {
{});
}

void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
mock_cert_verifier_.SetUpCommandLine(command_line);
}

void SetUpInProcessBrowserTestFixture() override {
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
}

void TearDownInProcessBrowserTestFixture() override {
mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
}

void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
content::SetBrowserClientForTesting(&test_content_browser_client_);
mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
host_resolver()->AddRule("*", "127.0.0.1");

embedded_test_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_OK);

ASSERT_TRUE(test_server_handle_ =
embedded_test_server()->StartAndReturnHandle());

// This is intentional to trigger
// TestBraveContentBrowserClient::RegisterBrowserInterfaceBindersForFrame
NavigateToURLAndWaitForLoadStop(browser(), GURL("brave://settings"));
ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), GURL("brave://settings")));

GURL url = embedded_test_server()->GetURL("/empty.html");
NavigateToURLAndWaitForLoadStop(browser(), url);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

ASSERT_TRUE(base::FeatureList::IsEnabled(
brave_wallet::features::kNativeBraveWalletFeature));
Expand All @@ -465,11 +481,6 @@ class SolanaProviderRendererTest : public InProcessBrowserTest {
return browser->tab_strip_model()->GetActiveWebContents();
}

void NavigateToURLAndWaitForLoadStop(Browser* browser, const GURL& url) {
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser, url)) << ":" << url;
ASSERT_TRUE(WaitForLoadStop(web_contents(browser))) << ":" << url;
}

void ReloadAndWaitForLoadStop(Browser* browser) {
chrome::Reload(browser, WindowOpenDisposition::CURRENT_TAB);
ASSERT_TRUE(content::WaitForLoadStop(web_contents(browser)));
Expand All @@ -480,6 +491,7 @@ class SolanaProviderRendererTest : public InProcessBrowserTest {
base::test::ScopedFeatureList feature_list_;

private:
content::ContentMockCertVerifier mock_cert_verifier_;
net::test_server::EmbeddedTestServerHandle test_server_handle_;
};

Expand All @@ -501,7 +513,7 @@ IN_PROC_BROWSER_TEST_F(SolanaProviderDisabledTest, SolanaObject) {
IN_PROC_BROWSER_TEST_F(SolanaProviderRendererTest, Incognito) {
Browser* private_browser = CreateIncognitoBrowser(nullptr);
GURL url = embedded_test_server()->GetURL("/empty.html");
NavigateToURLAndWaitForLoadStop(private_browser, url);
ASSERT_TRUE(ui_test_utils::NavigateToURL(private_browser, url));

auto result = EvalJs(web_contents(private_browser), CheckSolanaProviderScript,
content::EXECUTE_SCRIPT_USE_MANUAL_REPLY);
Expand Down Expand Up @@ -979,7 +991,7 @@ IN_PROC_BROWSER_TEST_F(SolanaProviderRendererTest, NonConfigurable) {
browser()->profile()->GetPrefs(),
brave_wallet::mojom::DefaultWallet::BraveWallet);
GURL url = embedded_test_server()->GetURL("/empty.html");
NavigateToURLAndWaitForLoadStop(browser(), url);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
std::string overwrite =
R"(try {
Object.defineProperty(window, 'solana', {
Expand All @@ -992,3 +1004,28 @@ IN_PROC_BROWSER_TEST_F(SolanaProviderRendererTest, NonConfigurable) {
EXPECT_TRUE(
content::EvalJs(web_contents(browser()), overwrite).ExtractBool());
}

IN_PROC_BROWSER_TEST_F(SolanaProviderRendererTest, Block3PIframe) {
GURL top_url(embedded_test_server()->GetURL("a.com", "/iframe.html"));
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), top_url));
// third party
GURL iframe_url_3p(embedded_test_server()->GetURL("b.com", "/"));
EXPECT_TRUE(
NavigateIframeToURL(web_contents(browser()), "test", iframe_url_3p));

constexpr char kEvalSolana[] = R"(typeof window.solana === 'undefined')";

content::RenderFrameHost* main_frame =
web_contents(browser())->GetMainFrame();
auto* iframe_rfh = ChildFrameAt(main_frame, 0);
ASSERT_TRUE(iframe_rfh);
EXPECT_TRUE(content::EvalJs(iframe_rfh, kEvalSolana).ExtractBool());

// same party
GURL iframe_url_1p(embedded_test_server()->GetURL("a.com", "/"));
EXPECT_TRUE(
NavigateIframeToURL(web_contents(browser()), "test", iframe_url_1p));
iframe_rfh = ChildFrameAt(main_frame, 0);
ASSERT_TRUE(iframe_rfh);
EXPECT_FALSE(content::EvalJs(iframe_rfh, kEvalSolana).ExtractBool());
}
5 changes: 5 additions & 0 deletions renderer/brave_wallet/brave_wallet_render_frame_observer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ void BraveWalletRenderFrameObserver::DidCreateScriptContext(
js_ethereum_provider_.reset();
return;
}
// Wallet provider objects won't be generated for third party iframe
if (!render_frame()->IsMainFrame() &&
render_frame()->GetWebFrame()->IsCrossOriginToMainFrame()) {
return;
}

bool is_main_world = world_id == content::ISOLATED_WORLD_ID_GLOBAL;
if (!js_ethereum_provider_) {
Expand Down
53 changes: 46 additions & 7 deletions renderer/test/js_ethereum_provider_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "url/gurl.h"
Expand All @@ -41,18 +42,33 @@ class JSEthereumProviderBrowserTest : public InProcessBrowserTest {
brave::RegisterPathProvider();
base::FilePath test_data_dir;
base::PathService::Get(brave::DIR_TEST_DATA, &test_data_dir);
https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
https_server_.ServeFilesFromDirectory(test_data_dir);
}

~JSEthereumProviderBrowserTest() override = default;

void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
mock_cert_verifier_.SetUpCommandLine(command_line);
}

void SetUpInProcessBrowserTestFixture() override {
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
}

void TearDownInProcessBrowserTestFixture() override {
mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
}

void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();

EXPECT_TRUE(https_server_.Start());
mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
// Map all hosts to localhost.
host_resolver()->AddRule("*", "127.0.0.1");
EXPECT_TRUE(https_server_.Start());
}

content::WebContents* web_contents() {
Expand All @@ -74,14 +90,15 @@ class JSEthereumProviderBrowserTest : public InProcessBrowserTest {
}

protected:
content::ContentMockCertVerifier mock_cert_verifier_;
net::EmbeddedTestServer https_server_;
};

IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest, AttachOnReload) {
brave_wallet::SetDefaultWallet(browser()->profile()->GetPrefs(),
brave_wallet::mojom::DefaultWallet::None);
const GURL url = https_server_.GetURL("/simple.html");
NavigateToURLAndWaitForLoadStop(url);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

std::string command = "window.ethereum.isMetaMask";
EXPECT_TRUE(content::EvalJs(main_frame(), command)
Expand Down Expand Up @@ -112,7 +129,8 @@ IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest,
DoNotAttachToChromePages) {
brave_wallet::SetDefaultWallet(browser()->profile()->GetPrefs(),
brave_wallet::mojom::DefaultWallet::None);
NavigateToURLAndWaitForLoadStop(GURL("chrome://newtab/"));
ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab/")));

std::string command = "window.ethereum.isMetaMask";
EXPECT_TRUE(content::EvalJs(main_frame(), command,
Expand All @@ -135,7 +153,7 @@ IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest,

IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest, NonWritable) {
const GURL url = https_server_.GetURL("/simple.html");
NavigateToURLAndWaitForLoadStop(url);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

// window.ethereum.*
auto result =
Expand Down Expand Up @@ -164,7 +182,7 @@ IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest, NonWritable) {
// See https://github.com/brave/brave-browser/issues/22213 for details
IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest, IsMetaMaskWritable) {
const GURL url = https_server_.GetURL("/simple.html");
NavigateToURLAndWaitForLoadStop(url);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

std::string overwrite =
"window.ethereum.isMetaMask = false;"
Expand All @@ -177,7 +195,7 @@ IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest, NonConfigurable) {
browser()->profile()->GetPrefs(),
brave_wallet::mojom::DefaultWallet::BraveWallet);
const GURL url = https_server_.GetURL("/simple.html");
NavigateToURLAndWaitForLoadStop(url);
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
std::string overwrite =
R"(try {
Object.defineProperty(window, 'ethereum', {
Expand All @@ -189,3 +207,24 @@ IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest, NonConfigurable) {
)";
EXPECT_TRUE(content::EvalJs(main_frame(), overwrite).ExtractBool());
}

IN_PROC_BROWSER_TEST_F(JSEthereumProviderBrowserTest, Block3PIframe) {
GURL top_url(https_server_.GetURL("a.com", "/iframe.html"));
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), top_url));
// third party
GURL iframe_url_3p(https_server_.GetURL("b.com", "/"));
EXPECT_TRUE(NavigateIframeToURL(web_contents(), "test", iframe_url_3p));

constexpr char kEvalEthereum[] = R"(typeof window.ethereum === 'undefined')";

auto* iframe_rfh = ChildFrameAt(main_frame(), 0);
ASSERT_TRUE(iframe_rfh);
EXPECT_TRUE(content::EvalJs(iframe_rfh, kEvalEthereum).ExtractBool());

// same party
GURL iframe_url_1p(https_server_.GetURL("a.com", "/"));
EXPECT_TRUE(NavigateIframeToURL(web_contents(), "test", iframe_url_1p));
iframe_rfh = ChildFrameAt(main_frame(), 0);
ASSERT_TRUE(iframe_rfh);
EXPECT_FALSE(content::EvalJs(iframe_rfh, kEvalEthereum).ExtractBool());
}

0 comments on commit 92462c7

Please sign in to comment.