mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-23 16:01:17 +00:00
fix(security): harden exec approval boundaries
This commit is contained in:
@@ -8,6 +8,10 @@ import {
|
||||
requiresExecApproval,
|
||||
resolveExecApprovalsFromFile,
|
||||
} from "../infra/exec-approvals.js";
|
||||
import {
|
||||
describeInterpreterInlineEval,
|
||||
detectInterpreterInlineEvalArgv,
|
||||
} from "../infra/exec-inline-eval.js";
|
||||
import { detectCommandObfuscation } from "../infra/exec-obfuscation-detect.js";
|
||||
import { buildNodeShellCommand } from "../infra/node-shell.js";
|
||||
import { parsePreparedSystemRunPayload } from "../infra/system-run-approval-context.js";
|
||||
@@ -42,6 +46,7 @@ export type ExecuteNodeHostCommandParams = {
|
||||
agentId?: string;
|
||||
security: ExecSecurity;
|
||||
ask: ExecAsk;
|
||||
strictInlineEval?: boolean;
|
||||
timeoutSec?: number;
|
||||
defaultTimeoutSec: number;
|
||||
approvalRunningNoticeMs: number;
|
||||
@@ -129,6 +134,21 @@ export async function executeNodeHostCommand(
|
||||
});
|
||||
let analysisOk = baseAllowlistEval.analysisOk;
|
||||
let allowlistSatisfied = false;
|
||||
const inlineEvalHit =
|
||||
params.strictInlineEval === true
|
||||
? (baseAllowlistEval.segments
|
||||
.map((segment) =>
|
||||
detectInterpreterInlineEvalArgv(segment.resolution?.effectiveArgv ?? segment.argv),
|
||||
)
|
||||
.find((entry) => entry !== null) ?? null)
|
||||
: null;
|
||||
if (inlineEvalHit) {
|
||||
params.warnings.push(
|
||||
`Warning: strict inline-eval mode requires explicit approval for ${describeInterpreterInlineEval(
|
||||
inlineEvalHit,
|
||||
)}.`,
|
||||
);
|
||||
}
|
||||
if (hostAsk === "on-miss" && hostSecurity === "allowlist" && analysisOk) {
|
||||
try {
|
||||
const approvalsSnapshot = await callGatewayTool<{ file: string }>(
|
||||
@@ -176,7 +196,9 @@ export async function executeNodeHostCommand(
|
||||
security: hostSecurity,
|
||||
analysisOk,
|
||||
allowlistSatisfied,
|
||||
}) || obfuscation.detected;
|
||||
}) ||
|
||||
inlineEvalHit !== null ||
|
||||
obfuscation.detected;
|
||||
const invokeTimeoutMs = Math.max(
|
||||
10_000,
|
||||
(typeof params.timeoutSec === "number" ? params.timeoutSec : params.defaultTimeoutSec) * 1000 +
|
||||
@@ -200,7 +222,10 @@ export async function executeNodeHostCommand(
|
||||
agentId: runAgentId,
|
||||
sessionKey: runSessionKey,
|
||||
approved: approvedByAsk,
|
||||
approvalDecision: approvalDecision ?? undefined,
|
||||
approvalDecision:
|
||||
approvalDecision === "allow-always" && inlineEvalHit !== null
|
||||
? "allow-once"
|
||||
: (approvalDecision ?? undefined),
|
||||
runId: runId ?? undefined,
|
||||
suppressNotifyOnExit: suppressNotifyOnExit === true ? true : undefined,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user