refactor(ui): change Lighthouse AI MCP tool filtering from blacklist to whitelist (#9802)

This commit is contained in:
Rubén De la Torre Vico
2026-01-15 13:53:05 +01:00
committed by GitHub
parent d8c1273a57
commit 31845df1a7
3 changed files with 54 additions and 27 deletions

View File

@@ -14,6 +14,7 @@ All notable changes to the **Prowler UI** are documented in this file.
### 🔄 Changed
- Refactor Lighthouse AI MCP tool filtering from blacklist to whitelist approach for improved security [(#9802)](https://github.com/prowler-cloud/prowler/pull/9802)
- Refactor ScatterPlot as reusable generic component with TypeScript generics [(#9664)](https://github.com/prowler-cloud/prowler/pull/9664)
- Swap Risk Plot axes: X = Fail Findings, Y = Prowler ThreatScore [(#9664)](https://github.com/prowler-cloud/prowler/pull/9664)
- Remove duplicate scan_id filter badge from Findings page [(#9664)](https://github.com/prowler-cloud/prowler/pull/9664)

View File

@@ -6,7 +6,7 @@ import { addBreadcrumb, captureException } from "@sentry/nextjs";
import { z } from "zod";
import { getMCPTools, isMCPAvailable } from "@/lib/lighthouse/mcp-client";
import { isBlockedTool } from "@/lib/lighthouse/workflow";
import { isAllowedTool } from "@/lib/lighthouse/workflow";
/** Input type for describe_tool */
interface DescribeToolInput {
@@ -34,8 +34,8 @@ function getAllTools(): StructuredTool[] {
*/
export const describeTool = tool(
async ({ toolName }: DescribeToolInput) => {
// Block destructive tools from being described
if (isBlockedTool(toolName)) {
// Only allow whitelisted tools to be described
if (!isAllowedTool(toolName)) {
return {
found: false,
message: `Tool '${toolName}' is not available.`,
@@ -116,11 +116,11 @@ Returns:
*/
export const executeTool = tool(
async ({ toolName, toolInput }: ExecuteToolInput) => {
// Block destructive tools from being executed
if (isBlockedTool(toolName)) {
// Only allow whitelisted tools to be executed
if (!isAllowedTool(toolName)) {
addBreadcrumb({
category: "meta-tool",
message: `execute_tool: Blocked tool attempted: ${toolName}`,
message: `execute_tool: Non-whitelisted tool attempted: ${toolName}`,
level: "warning",
data: { toolName, toolInput },
});

View File

@@ -40,33 +40,59 @@ function truncateDescription(desc: string | undefined, maxLen: number): string {
}
/**
* Tools that are blocked from being listed and executed by the LLM.
* These are destructive or sensitive operations that should only be
* performed through the UI with explicit user action.
* Tools explicitly allowed for the LLM to list and execute.
* Follows the principle of least privilege - only these tools are accessible.
* All other tools are blocked by default.
*/
const BLOCKED_TOOLS = new Set([
"prowler_app_connect_provider",
"prowler_app_delete_provider",
"prowler_app_trigger_scan",
"prowler_app_schedule_daily_scan",
"prowler_app_update_scan",
"prowler_app_delete_mutelist",
"prowler_app_set_mutelist",
"prowler_app_create_mute_rule",
"prowler_app_update_mute_rule",
"prowler_app_delete_mute_rule",
const ALLOWED_TOOLS = new Set([
// === Prowler Hub Tools - read-only ===
"prowler_hub_list_checks",
"prowler_hub_semantic_search_checks",
"prowler_hub_get_check_details",
"prowler_hub_get_check_code",
"prowler_hub_get_check_fixer",
"prowler_hub_list_compliances",
"prowler_hub_semantic_search_compliances",
"prowler_hub_get_compliance_details",
"prowler_hub_list_providers",
"prowler_hub_get_provider_services",
// === Prowler Docs Tools - read-only ===
"prowler_docs_search",
"prowler_docs_get_document",
// === Prowler App Tools - read-only ===
// Findings
"prowler_app_search_security_findings",
"prowler_app_get_finding_details",
"prowler_app_get_findings_overview",
// Providers
"prowler_app_search_providers",
// Scans
"prowler_app_list_scans",
"prowler_app_get_scan",
// Muting
"prowler_app_get_mutelist",
"prowler_app_list_mute_rules",
"prowler_app_get_mute_rule",
// Compliance
"prowler_app_get_compliance_overview",
"prowler_app_get_compliance_framework_state_details",
// Resources
"prowler_app_list_resources",
"prowler_app_get_resource",
"prowler_app_get_resources_overview",
]);
/**
* Check if a tool is blocked
* Check if a tool is allowed for LLM access.
* Returns true only if the tool is explicitly in the whitelist.
*/
export function isBlockedTool(toolName: string): boolean {
return BLOCKED_TOOLS.has(toolName);
export function isAllowedTool(toolName: string): boolean {
return ALLOWED_TOOLS.has(toolName);
}
/**
* Generate dynamic tool listing from MCP tools
* Filters out blocked/destructive tools
* Generate dynamic tool listing from MCP tools.
* Only includes tools that are explicitly whitelisted.
*/
function generateToolListing(): string {
if (!isMCPAvailable()) {
@@ -79,8 +105,8 @@ function generateToolListing(): string {
return TOOLS_UNAVAILABLE_MESSAGE;
}
// Filter out blocked tools
const safeTools = mcpTools.filter((tool) => !isBlockedTool(tool.name));
// Only include whitelisted tools
const safeTools = mcpTools.filter((tool) => isAllowedTool(tool.name));
let listing = "\n## Available Prowler Tools\n\n";
listing += `${safeTools.length} tools loaded from Prowler MCP\n\n`;