Skip to content

Commit

Permalink
Prevent external favicons fetch on password manager page. (#27066)
Browse files Browse the repository at this point in the history
* Prevent external favicons fetch on password manager page.

* Add test.
  • Loading branch information
goodov authored Dec 20, 2024
1 parent 190df44 commit 6a75a93
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 0 deletions.
22 changes: 22 additions & 0 deletions browser/password_manager/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (c) 2024 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at https://mozilla.org/MPL/2.0/.

if (!is_android) {
source_set("browser_tests") {
testonly = true
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]

sources = [ "password_manager_browsertest.cc" ]

deps = [
"//brave/browser",
"//chrome/browser",
"//chrome/browser/ui",
"//chrome/test:test_support",
"//chrome/test:test_support_ui",
"//content/test:test_support",
]
}
}
98 changes: 98 additions & 0 deletions browser/password_manager/password_manager_browsertest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* Copyright (c) 2024 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "base/test/bind.h"
#include "chrome/browser/password_manager/profile_password_store_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/test/base/chrome_test_utils.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/password_manager/core/browser/password_form_manager_for_ui.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "url/gurl.h"

class PasswordManagerTest : public InProcessBrowserTest {
public:
PasswordManagerTest() = default;
~PasswordManagerTest() override = default;

void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();
store_ = ProfilePasswordStoreFactory::GetForProfile(
browser()->profile(), ServiceAccessType::EXPLICIT_ACCESS);
}

protected:
scoped_refptr<password_manager::PasswordStoreInterface> store_;
};

IN_PROC_BROWSER_TEST_F(PasswordManagerTest,
SavePasswordAndOpenSettingsNoErrors) {
// Create test credentials.
password_manager::PasswordForm form;
form.url = GURL("https://example.com");
form.signon_realm = "https://example.com";
form.username_value = u"test_user";
form.password_value = u"test_password";
form.scheme = password_manager::PasswordForm::Scheme::kHtml;
base::RunLoop run_loop;
store_->AddLogin(form, run_loop.QuitClosure());
run_loop.Run();

// Open password settings and expect no errors.
content::WebContents* contents =
chrome_test_utils::GetActiveWebContents(this);
content::WebContentsConsoleObserver console_observer(contents);
console_observer.SetFilter(base::BindLambdaForTesting(
[](const content::WebContentsConsoleObserver::Message& message) {
return message.log_level == blink::mojom::ConsoleMessageLevel::kError;
}));
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), GURL(chrome::kChromeUIPasswordManagerURL)));

// Wait for the password list to be populated.
EXPECT_TRUE(content::ExecJs(contents, R"(
(async () => {
new Promise((resolve) => {
function queryShadowRoot(node, selector) {
const nodes = [...node.querySelectorAll(selector)];
const nodeIterator = document.createNodeIterator(
node,
NodeFilter.SHOW_ELEMENT,
(node) =>
node instanceof Element && node.shadowRoot
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_REJECT
);
for (
let currentNode = nodeIterator.nextNode();
currentNode;
currentNode = nodeIterator.nextNode()
) {
nodes.push(...queryShadowRoot(currentNode.shadowRoot, selector));
}
return nodes;
}
function checkPasswords() {
const password_items = queryShadowRoot(document, "password-list-item");
if (password_items.length > 0) {
resolve(true);
return;
}
setTimeout(checkPasswords, 100);
}
checkPasswords();
});
})();
)"));

EXPECT_TRUE(console_observer.messages().empty());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2024 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

import { RegisterPolymerTemplateModifications } from '//resources/brave/polymer_overriding.js'

RegisterPolymerTemplateModifications({
'site-favicon': (templateContent) => {
const downloadedFavicon =
templateContent.querySelector('#downloadedFavicon')
if (!downloadedFavicon) {
throw new Error(
`[Brave Password Manager Overrides] Could not find '#downloadedFavicon'`
)
} else {
downloadedFavicon.removeAttribute('auto-src')
}
}
})

export * from './site_favicon-chromium.js'
22 changes: 22 additions & 0 deletions chromium_src/tools/polymer/html_to_wrapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (c) 2024 The Brave Authors. All rights reserved.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at https://mozilla.org/MPL/2.0/.

import override_utils

POLYMER_OVERRIDING_TOKEN = '//resources/brave/polymer_overriding.js'
LIT_OVERRIDING_TOKEN = '//resources/brave/lit_overriding.js'


@override_utils.override_function(globals())
def detect_template_type(original_method, definition_file):
with open(definition_file, encoding='utf-8', mode='r') as f:
content = f.read()

if POLYMER_OVERRIDING_TOKEN in content:
return 'polymer'
if LIT_OVERRIDING_TOKEN in content:
return 'lit'

return original_method(definition_file)
11 changes: 11 additions & 0 deletions patches/tools-polymer-html_to_wrapper.py.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
diff --git a/tools/polymer/html_to_wrapper.py b/tools/polymer/html_to_wrapper.py
index 062ef045cecb11d5684806e2875439dad8efdfbd..5e699156c63ada808095ff67a8cbdb58189ebaba 100644
--- a/tools/polymer/html_to_wrapper.py
+++ b/tools/polymer/html_to_wrapper.py
@@ -282,5 +282,6 @@ def main(argv):
return


+from brave_chromium_utils import inline_chromium_src_override; inline_chromium_src_override(globals(), locals())
if __name__ == '__main__':
main(sys.argv[1:])
1 change: 1 addition & 0 deletions test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,7 @@ test("brave_browser_tests") {
"//brave/browser/ai_chat:browser_tests",
"//brave/browser/banners:browser_tests",
"//brave/browser/brave_ads/creatives/search_result_ad:browser_tests",
"//brave/browser/password_manager:browser_tests",
"//brave/browser/sharing_hub:browser_tests",
"//brave/browser/ui/ai_rewriter:browsertest",
"//brave/browser/ui/geolocation:browser_tests",
Expand Down

0 comments on commit 6a75a93

Please sign in to comment.