[AI Chat] [Content Agent] Block navigation to and using tools on extension store pages (#32576)

This commit is contained in:
Pete Miller
2025-11-27 19:09:21 +07:00
committed by GitHub
parent 7fdd82fd38
commit b5de58dc91
3 changed files with 80 additions and 0 deletions
@@ -19,6 +19,7 @@
#include "brave/components/ai_chat/core/common/features.h"
#include "brave/components/ai_chat/core/common/test_utils.h"
#include "chrome/browser/actor/actor_keyed_service_factory.h"
#include "chrome/browser/actor/actor_policy_checker.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
@@ -348,6 +349,39 @@ IN_PROC_BROWSER_TEST_F(ContentAgentToolsTest, NavigationTool_BasicNavigation) {
EXPECT_EQ(test_url.path(), final_url.path());
}
IN_PROC_BROWSER_TEST_F(ContentAgentToolsTest, BlockExtensionStore) {
// Verify that navigating to the extension store is blocked
NavigateToChromiumTestFile("/actor/page_with_clickable_element.html");
auto nav_tool = FindToolByName("web_page_navigator");
ASSERT_TRUE(nav_tool);
// Get initial URL
GURL initial_url = web_contents()->GetVisibleURL();
// Create input for navigating to a different test page
base::Value::Dict input;
input.Set("website_url", "https://chromewebstore.google.com/example");
auto result = ExecuteToolAndWait(nav_tool, *base::WriteJson(input), false);
EXPECT_GT(result.size(), 0u);
EXPECT_THAT(result, ContentBlockText(testing::HasSubstr("Error")));
// Verify the page could not navigate to the URL
GURL final_url = web_contents()->GetURL();
EXPECT_EQ(initial_url, final_url);
// Also verify that other actions won't be able to execute against tabs
// already on an extension store URL.
base::test::TestFuture<actor::MayActOnUrlBlockReason> allowed;
auto* actor_service =
actor::ActorKeyedServiceFactory::GetActorKeyedService(agent_profile_);
actor_service->GetPolicyChecker().MayActOnUrl(
GURL("https://chromewebstore.google.com/example"), false, agent_profile_,
actor_service->GetJournal(), actor::TaskId(), allowed.GetCallback());
EXPECT_NE(allowed.Take(), actor::MayActOnUrlBlockReason::kAllowed);
}
// Test drag and release tool with coordinates (since drag needs from/to)
IN_PROC_BROWSER_TEST_F(ContentAgentToolsTest,
DragAndReleaseTool_CoordinateTargets) {
@@ -0,0 +1,34 @@
// Copyright (c) 2025 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 "extensions/buildflags/buildflags.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/extension_urls.h"
#endif
namespace {
bool IsChromeWebStoreURL(const GURL& url) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
return (url.GetHost() == extension_urls::GetWebstoreLaunchURL().GetHost()) ||
(url.GetHost() == extension_urls::GetNewWebstoreLaunchURL().GetHost());
#else
return false;
#endif
}
} // namespace
// Add Brave-specific restrictions
#define BRAVE_MAY_ACT_ON_URL_INTERNAL \
if (IsChromeWebStoreURL(url)) { \
decision_wrapper->Reject( \
"Extension store URL", \
actor::MayActOnUrlBlockReason::kUrlNotInAllowlist); \
return; \
}
#include <chrome/browser/actor/site_policy.cc>
#undef BRAVE_MAY_ACT_ON_URL_INTERNAL
@@ -0,0 +1,12 @@
diff --git a/chrome/browser/actor/site_policy.cc b/chrome/browser/actor/site_policy.cc
index e4dc851408f20fbc02d06110c10f441a3e77c79c..b5a670ac861c6c7840877ca8260f5f45b44d49fc 100644
--- a/chrome/browser/actor/site_policy.cc
+++ b/chrome/browser/actor/site_policy.cc
@@ -169,6 +169,7 @@ void MayActOnUrlInternal(
return;
}
+ BRAVE_MAY_ACT_ON_URL_INTERNAL
if (DisableSafetyChecks()) {
decision_wrapper->Accept();
return;