diff --git a/CHANGELOG.md b/CHANGELOG.md index 390bbb0f65d..9b1a3e15899 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Exec approvals: treat bare allowlist `*` as a true wildcard for parsed executables, including unresolved PATH lookups, so global opt-in allowlists work as configured. (#25250) Thanks @widingmarcus-cyber. - Gateway/Auth: allow trusted-proxy authenticated Control UI websocket sessions to skip device pairing when device identity is absent, preventing false `pairing required` failures behind trusted reverse proxies. (#25428) Thanks @SidQin-cyber. - Agents/Tool dispatch: await block-reply flush before tool execution starts so buffered block replies preserve message ordering around tool calls. (#25427) Thanks @SidQin-cyber. - macOS/Menu bar: stop reusing the injector delegate for the "Usage cost (30 days)" submenu to prevent recursive submenu injection loops when opening cost history. (#25341) Thanks @yingchunbai. diff --git a/src/infra/exec-command-resolution.ts b/src/infra/exec-command-resolution.ts index c2c2f3fe230..d102a1030f1 100644 --- a/src/infra/exec-command-resolution.ts +++ b/src/infra/exec-command-resolution.ts @@ -226,9 +226,9 @@ export function matchAllowlist( if (!entries.length) { return null; } - // A bare "*" wildcard allows any command regardless of resolution. - // Check it before the resolvedPath guard so that unresolvable commands - // (e.g. Windows executables without known extensions) still match. + // A bare "*" wildcard allows any parsed executable command. + // Check it before the resolvedPath guard so unresolved PATH lookups still + // match (for example platform-specific executables without known extensions). const bareWild = entries.find((e) => e.pattern?.trim() === "*"); if (bareWild && resolution) { return bareWild; @@ -242,12 +242,6 @@ export function matchAllowlist( if (!pattern) { continue; } - // A bare "*" wildcard means "allow any executable". Match immediately - // without going through glob expansion (glob `*` maps to `[^/]*` which - // would fail on absolute paths containing slashes). - if (pattern === "*") { - return entry; - } const hasPath = pattern.includes("/") || pattern.includes("\\") || pattern.includes("~"); if (!hasPath) { continue;