Skip to content

Commit

Permalink
Sanitize URL when it is copied into clipboard by JS. (#24207)
Browse files Browse the repository at this point in the history
* Sanitize URL when it is copied into clipboard by JS.
  • Loading branch information
boocmp authored Jun 28, 2024
1 parent 9b030c2 commit 8c27621
Show file tree
Hide file tree
Showing 29 changed files with 849 additions and 98 deletions.
4 changes: 4 additions & 0 deletions browser/brave_browser_features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ BASE_FEATURE(kBraveCopyCleanLinkByDefault,
#endif
);

BASE_FEATURE(kBraveCopyCleanLinkFromJs,
"BraveCopyCleanLinkFromJs",
base::FEATURE_DISABLED_BY_DEFAULT);

// Disable download warnings for dangerous files when Safe Browsing is
// disabled.
BASE_FEATURE(kBraveOverrideDownloadDangerLevel,
Expand Down
1 change: 1 addition & 0 deletions browser/brave_browser_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace features {

BASE_DECLARE_FEATURE(kBraveCleanupSessionCookiesOnSessionRestore);
BASE_DECLARE_FEATURE(kBraveCopyCleanLinkByDefault);
BASE_DECLARE_FEATURE(kBraveCopyCleanLinkFromJs);
BASE_DECLARE_FEATURE(kBraveOverrideDownloadDangerLevel);
BASE_DECLARE_FEATURE(kBraveWebViewRoundedCorners);
BASE_DECLARE_FEATURE(kBraveDayZeroExperiment);
Expand Down
22 changes: 22 additions & 0 deletions browser/brave_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "base/strings/strcat.h"
#include "base/system/sys_info.h"
#include "brave/browser/brave_ads/ads_service_factory.h"
#include "brave/browser/brave_browser_features.h"
#include "brave/browser/brave_browser_main_extra_parts.h"
#include "brave/browser/brave_browser_process.h"
#include "brave/browser/brave_shields/brave_shields_web_contents_observer.h"
Expand All @@ -35,6 +36,7 @@
#include "brave/browser/skus/skus_service_factory.h"
#include "brave/browser/ui/brave_ui_features.h"
#include "brave/browser/ui/webui/skus_internals_ui.h"
#include "brave/browser/url_sanitizer/url_sanitizer_service_factory.h"
#include "brave/components/ai_chat/core/common/buildflags/buildflags.h"
#include "brave/components/ai_rewriter/common/buildflags/buildflags.h"
#include "brave/components/body_sniffer/body_sniffer_throttle.h"
Expand Down Expand Up @@ -80,6 +82,7 @@
#include "brave/components/speedreader/common/buildflags/buildflags.h"
#include "brave/components/tor/buildflags/buildflags.h"
#include "brave/components/translate/core/common/brave_translate_switches.h"
#include "brave/components/url_sanitizer/browser/url_sanitizer_service.h"
#include "brave/grit/brave_generated_resources.h"
#include "brave/third_party/blink/renderer/brave_farbling_constants.h"
#include "build/build_config.h"
Expand Down Expand Up @@ -1351,3 +1354,22 @@ blink::UserAgentMetadata BraveContentBrowserClient::GetUserAgentMetadata() {
base::StrCat({base::NumberToString(version.components()[0]), ".0.0.0"});
return metadata;
}

GURL BraveContentBrowserClient::SanitizeURL(
content::RenderFrameHost* render_frame_host,
const GURL& url) {
if (!base::FeatureList::IsEnabled(features::kBraveCopyCleanLinkFromJs)) {
return url;
}
CHECK(render_frame_host);
CHECK(render_frame_host->GetBrowserContext());
auto* url_sanitizer_service =
brave::URLSanitizerServiceFactory::GetForBrowserContext(
render_frame_host->GetBrowserContext());
CHECK(url_sanitizer_service);
if (!url_sanitizer_service->CheckJsPermission(
render_frame_host->GetLastCommittedURL())) {
return url;
}
return url_sanitizer_service->SanitizeURL(url);
}
3 changes: 3 additions & 0 deletions browser/brave_content_browser_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ class BraveContentBrowserClient : public ChromeContentBrowserClient {
blink::web_pref::WebPreferences* prefs) override;
blink::UserAgentMetadata GetUserAgentMetadata() override;

GURL SanitizeURL(content::RenderFrameHost* render_frame_host,
const GURL& url) override;

private:
void OnAllowGoogleAuthChanged();

Expand Down
45 changes: 28 additions & 17 deletions browser/ui/views/omnibox/brave_omnibox_view_views_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "brave/browser/brave_browser_features.h"
#include "brave/browser/ui/views/omnibox/brave_omnibox_view_views.h"

#include "brave/browser/brave_browser_features.h"
#include "brave/browser/url_sanitizer/url_sanitizer_service_factory.h"
#include "brave/components/url_sanitizer/browser/url_sanitizer_service.h"
#include "build/build_config.h"
Expand Down Expand Up @@ -55,6 +56,24 @@ class BraveOmniboxViewViewsTest : public InProcessBrowserTest {
return browser_view->toolbar()->location_bar();
}
OmniboxViewViews* omnibox_view() { return location_bar()->omnibox_view(); }

void SetSanitizerRules(const std::string& matchers) {
base::RunLoop loop;

auto* url_sanitizer_service =
brave::URLSanitizerServiceFactory::GetForBrowserContext(
browser()->profile());
url_sanitizer_service->SetInitializationCallbackForTesting(
loop.QuitClosure());
brave::URLSanitizerComponentInstaller::RawConfig config;
config.matchers = matchers;
auto* component_intaller =
static_cast<brave::URLSanitizerComponentInstaller::Observer*>(
url_sanitizer_service);
component_intaller->OnConfigReady(config);

loop.Run();
}
};

class BraveOmniboxViewViewsEnabledFeatureTest
Expand Down Expand Up @@ -156,21 +175,18 @@ IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest,
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
std::string text_from_clipboard;
clipboard->ReadAsciiText(ui::ClipboardBuffer::kCopyPaste,
/* data_dst = */ nullptr,
&text_from_clipboard);
/* data_dst = */ nullptr, &text_from_clipboard);
EXPECT_EQ(test_url, text_from_clipboard);

#if BUILDFLAG(IS_LINUX)
clipboard->ReadAsciiText(ui::ClipboardBuffer::kSelection,
/* data_dst = */ nullptr,
&text_from_clipboard);
/* data_dst = */ nullptr, &text_from_clipboard);
EXPECT_EQ(test_url, text_from_clipboard);
#endif
}

IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, CopyCleanURLToClipboardTest) {
brave::URLSanitizerServiceFactory::GetForBrowserContext(browser()->profile())
->Initialize(R"([
SetSanitizerRules(R"([
{ "include": [ "*://*/*"], "params": ["utm_content"] }
])");
const std::string test_url(
Expand All @@ -192,8 +208,7 @@ IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, CopyCleanURLToClipboardTest) {
}

IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, CopyURLToClipboardTest) {
brave::URLSanitizerServiceFactory::GetForBrowserContext(browser()->profile())
->Initialize(R"([
SetSanitizerRules(R"([
{ "include": [ "*://*/*"], "params": ["utm_content"] }
])");
const std::string test_url(
Expand All @@ -216,8 +231,7 @@ IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, CopyURLToClipboardTest) {

IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsEnabledFeatureTest,
CopyCleanedURLToClipboardByHotkey) {
brave::URLSanitizerServiceFactory::GetForBrowserContext(browser()->profile())
->Initialize(R"([
SetSanitizerRules(R"([
{ "include": [ "*://*/*"], "params": ["utm_content"] }
])");
const std::string test_url(
Expand All @@ -244,8 +258,7 @@ IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsEnabledFeatureTest,
IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, DoNotSanitizeInternalURLS) {
const std::string test_url("brave://settings/?utm_ad=1");
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(test_url)));
brave::URLSanitizerServiceFactory::GetForBrowserContext(browser()->profile())
->Initialize(R"([
SetSanitizerRules(R"([
{ "include": [ "*://*/*"], "params": ["utm_ad"] }
])");
base::RunLoop().RunUntilIdle();
Expand All @@ -261,8 +274,7 @@ IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, DoNotSanitizeInternalURLS) {

IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsDisabledFeatureTest,
CopyCleanedURLToClipboardByHotkey) {
brave::URLSanitizerServiceFactory::GetForBrowserContext(browser()->profile())
->Initialize(R"([
SetSanitizerRules(R"([
{ "include": [ "*://*/*"], "params": ["utm_content"] }
])");
const std::string test_url(
Expand All @@ -287,8 +299,7 @@ IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsDisabledFeatureTest,
}

IN_PROC_BROWSER_TEST_F(BraveOmniboxViewViewsTest, CopyTextToClipboardByHotkey) {
brave::URLSanitizerServiceFactory::GetForBrowserContext(browser()->profile())
->Initialize(R"([
SetSanitizerRules(R"([
{ "include": [ "*://*/*"], "params": ["utm_content"] }
])");
const std::string test_text(
Expand Down
22 changes: 22 additions & 0 deletions browser/url_sanitizer/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/.

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

sources = [ "url_sanitizer_browsertest.cc" ]
deps = [
"//brave/components/url_sanitizer/browser",
"//chrome/browser",
"//chrome/browser/profiles:profile",
"//chrome/browser/ui",
"//chrome/test:test_support",
"//content/public/browser",
"//content/test:test_support",
"//testing/gmock",
"//testing/gtest",
]
}
Loading

0 comments on commit 8c27621

Please sign in to comment.