mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-03 03:03:24 -04:00
refactor(security): centralize dangerous tool lists
This commit is contained in:
@@ -10,24 +10,7 @@ import { spawn, type ChildProcess } from "node:child_process";
|
||||
import * as readline from "node:readline";
|
||||
import { Readable, Writable } from "node:stream";
|
||||
import { ensureOpenClawCliOnPath } from "../infra/path-env.js";
|
||||
|
||||
/**
|
||||
* Tools that require explicit user approval in ACP sessions.
|
||||
* These tools can execute arbitrary code, modify the filesystem,
|
||||
* or access sensitive resources.
|
||||
*/
|
||||
const DANGEROUS_ACP_TOOLS = new Set([
|
||||
"exec",
|
||||
"spawn",
|
||||
"shell",
|
||||
"sessions_spawn",
|
||||
"sessions_send",
|
||||
"gateway",
|
||||
"fs_write",
|
||||
"fs_delete",
|
||||
"fs_move",
|
||||
"apply_patch",
|
||||
]);
|
||||
import { DANGEROUS_ACP_TOOLS } from "../security/dangerous-tools.js";
|
||||
|
||||
const SAFE_AUTO_APPROVE_KINDS = new Set(["read", "search"]);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import { logWarn } from "../logger.js";
|
||||
import { isTestDefaultMemorySlotDisabled } from "../plugins/config-state.js";
|
||||
import { getPluginToolMeta } from "../plugins/tools.js";
|
||||
import { isSubagentSessionKey } from "../routing/session-key.js";
|
||||
import { DEFAULT_GATEWAY_HTTP_TOOL_DENY } from "../security/dangerous-tools.js";
|
||||
import { normalizeMessageChannel } from "../utils/message-channel.js";
|
||||
import { authorizeGatewayConnect, type ResolvedGatewayAuth } from "./auth.js";
|
||||
import {
|
||||
@@ -36,22 +37,6 @@ import { getBearerToken, getHeader } from "./http-utils.js";
|
||||
const DEFAULT_BODY_BYTES = 2 * 1024 * 1024;
|
||||
const MEMORY_TOOL_NAMES = new Set(["memory_search", "memory_get"]);
|
||||
|
||||
/**
|
||||
* Tools denied via HTTP /tools/invoke regardless of session policy.
|
||||
* Prevents RCE and privilege escalation from HTTP API surface.
|
||||
* Configurable via gateway.tools.{deny,allow} in openclaw.json.
|
||||
*/
|
||||
const DEFAULT_GATEWAY_HTTP_TOOL_DENY = [
|
||||
// Session orchestration — spawning agents remotely is RCE
|
||||
"sessions_spawn",
|
||||
// Cross-session injection — message injection across sessions
|
||||
"sessions_send",
|
||||
// Gateway control plane — prevents gateway reconfiguration via HTTP
|
||||
"gateway",
|
||||
// Interactive setup — requires terminal QR scan, hangs on HTTP
|
||||
"whatsapp_login",
|
||||
];
|
||||
|
||||
type ToolsInvokeBody = {
|
||||
tool?: unknown;
|
||||
action?: unknown;
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
formatPermissionRemediation,
|
||||
inspectPathPermissions,
|
||||
} from "./audit-fs.js";
|
||||
import { DEFAULT_GATEWAY_HTTP_TOOL_DENY } from "./dangerous-tools.js";
|
||||
|
||||
export type SecurityAuditSeverity = "info" | "warn" | "critical";
|
||||
|
||||
@@ -269,8 +270,9 @@ function collectGatewayConfigFindings(
|
||||
.map((v) => (typeof v === "string" ? v.trim().toLowerCase() : ""))
|
||||
.filter(Boolean),
|
||||
);
|
||||
const defaultHttpDeniedTools = ["sessions_spawn", "sessions_send", "gateway", "whatsapp_login"];
|
||||
const reenabledOverHttp = defaultHttpDeniedTools.filter((name) => gatewayToolsAllow.has(name));
|
||||
const reenabledOverHttp = DEFAULT_GATEWAY_HTTP_TOOL_DENY.filter((name) =>
|
||||
gatewayToolsAllow.has(name),
|
||||
);
|
||||
if (reenabledOverHttp.length > 0) {
|
||||
const extraRisk = bind !== "loopback" || tailscaleMode === "funnel";
|
||||
findings.push({
|
||||
|
||||
37
src/security/dangerous-tools.ts
Normal file
37
src/security/dangerous-tools.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
// Shared tool-risk constants.
|
||||
// Keep these centralized so gateway HTTP restrictions, security audits, and ACP prompts don't drift.
|
||||
|
||||
/**
|
||||
* Tools denied via Gateway HTTP `POST /tools/invoke` by default.
|
||||
* These are high-risk because they enable session orchestration, control-plane actions,
|
||||
* or interactive flows that don't make sense over a non-interactive HTTP surface.
|
||||
*/
|
||||
export const DEFAULT_GATEWAY_HTTP_TOOL_DENY = [
|
||||
// Session orchestration — spawning agents remotely is RCE
|
||||
"sessions_spawn",
|
||||
// Cross-session injection — message injection across sessions
|
||||
"sessions_send",
|
||||
// Gateway control plane — prevents gateway reconfiguration via HTTP
|
||||
"gateway",
|
||||
// Interactive setup — requires terminal QR scan, hangs on HTTP
|
||||
"whatsapp_login",
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* ACP tools that should always require explicit user approval.
|
||||
* ACP is an automation surface; we never want "silent yes" for mutating/execution tools.
|
||||
*/
|
||||
export const DANGEROUS_ACP_TOOL_NAMES = [
|
||||
"exec",
|
||||
"spawn",
|
||||
"shell",
|
||||
"sessions_spawn",
|
||||
"sessions_send",
|
||||
"gateway",
|
||||
"fs_write",
|
||||
"fs_delete",
|
||||
"fs_move",
|
||||
"apply_patch",
|
||||
] as const;
|
||||
|
||||
export const DANGEROUS_ACP_TOOLS = new Set<string>(DANGEROUS_ACP_TOOL_NAMES);
|
||||
Reference in New Issue
Block a user