mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-01-25 02:08:11 +00:00
refactor(ui): change Lighthouse AI MCP tool filtering from blacklist to whitelist (#9802)
This commit is contained in:
committed by
GitHub
parent
d8c1273a57
commit
31845df1a7
@@ -14,6 +14,7 @@ All notable changes to the **Prowler UI** are documented in this file.
|
|||||||
|
|
||||||
### 🔄 Changed
|
### 🔄 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)
|
- 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)
|
- 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)
|
- Remove duplicate scan_id filter badge from Findings page [(#9664)](https://github.com/prowler-cloud/prowler/pull/9664)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { addBreadcrumb, captureException } from "@sentry/nextjs";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { getMCPTools, isMCPAvailable } from "@/lib/lighthouse/mcp-client";
|
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 */
|
/** Input type for describe_tool */
|
||||||
interface DescribeToolInput {
|
interface DescribeToolInput {
|
||||||
@@ -34,8 +34,8 @@ function getAllTools(): StructuredTool[] {
|
|||||||
*/
|
*/
|
||||||
export const describeTool = tool(
|
export const describeTool = tool(
|
||||||
async ({ toolName }: DescribeToolInput) => {
|
async ({ toolName }: DescribeToolInput) => {
|
||||||
// Block destructive tools from being described
|
// Only allow whitelisted tools to be described
|
||||||
if (isBlockedTool(toolName)) {
|
if (!isAllowedTool(toolName)) {
|
||||||
return {
|
return {
|
||||||
found: false,
|
found: false,
|
||||||
message: `Tool '${toolName}' is not available.`,
|
message: `Tool '${toolName}' is not available.`,
|
||||||
@@ -116,11 +116,11 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
export const executeTool = tool(
|
export const executeTool = tool(
|
||||||
async ({ toolName, toolInput }: ExecuteToolInput) => {
|
async ({ toolName, toolInput }: ExecuteToolInput) => {
|
||||||
// Block destructive tools from being executed
|
// Only allow whitelisted tools to be executed
|
||||||
if (isBlockedTool(toolName)) {
|
if (!isAllowedTool(toolName)) {
|
||||||
addBreadcrumb({
|
addBreadcrumb({
|
||||||
category: "meta-tool",
|
category: "meta-tool",
|
||||||
message: `execute_tool: Blocked tool attempted: ${toolName}`,
|
message: `execute_tool: Non-whitelisted tool attempted: ${toolName}`,
|
||||||
level: "warning",
|
level: "warning",
|
||||||
data: { toolName, toolInput },
|
data: { toolName, toolInput },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -40,33 +40,59 @@ function truncateDescription(desc: string | undefined, maxLen: number): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tools that are blocked from being listed and executed by the LLM.
|
* Tools explicitly allowed for the LLM to list and execute.
|
||||||
* These are destructive or sensitive operations that should only be
|
* Follows the principle of least privilege - only these tools are accessible.
|
||||||
* performed through the UI with explicit user action.
|
* All other tools are blocked by default.
|
||||||
*/
|
*/
|
||||||
const BLOCKED_TOOLS = new Set([
|
const ALLOWED_TOOLS = new Set([
|
||||||
"prowler_app_connect_provider",
|
// === Prowler Hub Tools - read-only ===
|
||||||
"prowler_app_delete_provider",
|
"prowler_hub_list_checks",
|
||||||
"prowler_app_trigger_scan",
|
"prowler_hub_semantic_search_checks",
|
||||||
"prowler_app_schedule_daily_scan",
|
"prowler_hub_get_check_details",
|
||||||
"prowler_app_update_scan",
|
"prowler_hub_get_check_code",
|
||||||
"prowler_app_delete_mutelist",
|
"prowler_hub_get_check_fixer",
|
||||||
"prowler_app_set_mutelist",
|
"prowler_hub_list_compliances",
|
||||||
"prowler_app_create_mute_rule",
|
"prowler_hub_semantic_search_compliances",
|
||||||
"prowler_app_update_mute_rule",
|
"prowler_hub_get_compliance_details",
|
||||||
"prowler_app_delete_mute_rule",
|
"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 {
|
export function isAllowedTool(toolName: string): boolean {
|
||||||
return BLOCKED_TOOLS.has(toolName);
|
return ALLOWED_TOOLS.has(toolName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate dynamic tool listing from MCP tools
|
* Generate dynamic tool listing from MCP tools.
|
||||||
* Filters out blocked/destructive tools
|
* Only includes tools that are explicitly whitelisted.
|
||||||
*/
|
*/
|
||||||
function generateToolListing(): string {
|
function generateToolListing(): string {
|
||||||
if (!isMCPAvailable()) {
|
if (!isMCPAvailable()) {
|
||||||
@@ -79,8 +105,8 @@ function generateToolListing(): string {
|
|||||||
return TOOLS_UNAVAILABLE_MESSAGE;
|
return TOOLS_UNAVAILABLE_MESSAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter out blocked tools
|
// Only include whitelisted tools
|
||||||
const safeTools = mcpTools.filter((tool) => !isBlockedTool(tool.name));
|
const safeTools = mcpTools.filter((tool) => isAllowedTool(tool.name));
|
||||||
|
|
||||||
let listing = "\n## Available Prowler Tools\n\n";
|
let listing = "\n## Available Prowler Tools\n\n";
|
||||||
listing += `${safeTools.length} tools loaded from Prowler MCP\n\n`;
|
listing += `${safeTools.length} tools loaded from Prowler MCP\n\n`;
|
||||||
|
|||||||
Reference in New Issue
Block a user