From 68b7ffd59e5ae03421ee69c835fb9f8448b82692 Mon Sep 17 00:00:00 2001 From: Mariano Belinky Date: Wed, 8 Apr 2026 17:52:47 +0200 Subject: [PATCH] CLI: validate container hints --- src/cli/command-format.ts | 4 +++- src/cli/profile.test.ts | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/cli/command-format.ts b/src/cli/command-format.ts index b2b856d43fa..ecb9b687013 100644 --- a/src/cli/command-format.ts +++ b/src/cli/command-format.ts @@ -7,6 +7,7 @@ const PROFILE_FLAG_RE = /(?:^|\s)--profile(?:\s|=|$)/; const DEV_FLAG_RE = /(?:^|\s)--dev(?:\s|$)/; const UPDATE_COMMAND_RE = /^(?:pnpm|npm|bunx|npx)\s+openclaw\b.*(?:^|\s)update(?:\s|$)|^openclaw\b.*(?:^|\s)update(?:\s|$)/; +const CONTAINER_HINT_RE = /^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/; export function formatCliCommand( command: string, @@ -14,7 +15,8 @@ export function formatCliCommand( ): string { const cliName = resolveCliName(); const normalizedCommand = replaceCliName(command, cliName); - const container = env.OPENCLAW_CONTAINER_HINT?.trim(); + const rawContainer = env.OPENCLAW_CONTAINER_HINT?.trim(); + const container = rawContainer && CONTAINER_HINT_RE.test(rawContainer) ? rawContainer : undefined; const profile = normalizeProfileName(env.OPENCLAW_PROFILE); if (!container && !profile) { return normalizedCommand; diff --git a/src/cli/profile.test.ts b/src/cli/profile.test.ts index e2955d28412..3ce82c2dd48 100644 --- a/src/cli/profile.test.ts +++ b/src/cli/profile.test.ts @@ -214,6 +214,14 @@ describe("formatCliCommand", () => { ).toBe("openclaw --container demo gateway status --deep"); }); + it("ignores unsafe container hints", () => { + expect( + formatCliCommand("openclaw gateway status --deep", { + OPENCLAW_CONTAINER_HINT: "demo; rm -rf /", + }), + ).toBe("openclaw gateway status --deep"); + }); + it("preserves both --container and --profile hints", () => { expect( formatCliCommand("openclaw doctor", {