mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 10:29:58 +00:00
fix(node-host): sync rawCommand with hardened argv after executable path pinning
The security fix for GHSA-h3f9-mjwj-w476 added rawCommand/command[] consistency validation. After hardenApprovedExecutionPaths pins an executable to its absolute path (e.g. echo → /usr/bin/echo), the rawCommand was not updated, causing all nodes.run direct commands to fail validation. Regenerate rawCommand via formatExecCommand(hardening.argv) when hardening produces a new argv, so the consistency check passes. Closes #33080
This commit is contained in:
committed by
Gustavo Madeira Santana
parent
4fb40497d4
commit
fefb2fbe67
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { formatExecCommand } from "../infra/system-run-command.js";
|
||||
import {
|
||||
buildSystemRunApprovalPlan,
|
||||
hardenApprovedExecutionPaths,
|
||||
@@ -19,6 +20,7 @@ type HardeningCase = {
|
||||
withPathToken?: boolean;
|
||||
expectedArgv: (ctx: { pathToken: PathTokenSetup | null }) => string[];
|
||||
expectedCmdText?: string;
|
||||
checkRawCommandMatchesArgv?: boolean;
|
||||
};
|
||||
|
||||
describe("hardenApprovedExecutionPaths", () => {
|
||||
@@ -53,6 +55,14 @@ describe("hardenApprovedExecutionPaths", () => {
|
||||
withPathToken: true,
|
||||
expectedArgv: () => ["env", "poccmd", "SAFE"],
|
||||
},
|
||||
{
|
||||
name: "rawCommand matches hardened argv after executable path pinning",
|
||||
mode: "build-plan",
|
||||
argv: ["poccmd", "hello"],
|
||||
withPathToken: true,
|
||||
expectedArgv: ({ pathToken }) => [pathToken!.expected, "hello"],
|
||||
checkRawCommandMatchesArgv: true,
|
||||
},
|
||||
];
|
||||
|
||||
for (const testCase of cases) {
|
||||
@@ -82,6 +92,9 @@ describe("hardenApprovedExecutionPaths", () => {
|
||||
if (testCase.expectedCmdText) {
|
||||
expect(prepared.cmdText).toBe(testCase.expectedCmdText);
|
||||
}
|
||||
if (testCase.checkRawCommandMatchesArgv) {
|
||||
expect(prepared.plan.rawCommand).toBe(formatExecCommand(prepared.plan.argv));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from "node:path";
|
||||
import type { SystemRunApprovalPlan } from "../infra/exec-approvals.js";
|
||||
import { resolveCommandResolutionFromArgv } from "../infra/exec-command-resolution.js";
|
||||
import { sameFileIdentity } from "../infra/file-identity.js";
|
||||
import { resolveSystemRunCommand } from "../infra/system-run-command.js";
|
||||
import { formatExecCommand, resolveSystemRunCommand } from "../infra/system-run-command.js";
|
||||
|
||||
export type ApprovedCwdSnapshot = {
|
||||
cwd: string;
|
||||
@@ -239,12 +239,16 @@ export function buildSystemRunApprovalPlan(params: {
|
||||
if (!hardening.ok) {
|
||||
return { ok: false, message: hardening.message };
|
||||
}
|
||||
const rawCommand =
|
||||
hardening.argv === command.argv
|
||||
? command.cmdText.trim() || null
|
||||
: formatExecCommand(hardening.argv) || null;
|
||||
return {
|
||||
ok: true,
|
||||
plan: {
|
||||
argv: hardening.argv,
|
||||
cwd: hardening.cwd ?? null,
|
||||
rawCommand: command.cmdText.trim() || null,
|
||||
rawCommand,
|
||||
agentId: normalizeString(params.agentId),
|
||||
sessionKey: normalizeString(params.sessionKey),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user