fix: block side-effecting command wrappers [AI]#87292
Conversation
|
Codex review: needs maintainer review before merge. Reviewed May 27, 2026, 9:15 AM ET / 13:15 UTC. Summary PR surface: Source +82, Tests +96. Total +178 across 8 files. Reproducibility: yes. from source inspection: current main marks Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge Security Review detailsBest possible solution: Land the narrow fail-closed wrapper policy after maintainer acceptance of the compatibility change and relevant CI completion, keeping the focused regression tests and proof in place. Do we have a high-confidence way to reproduce the issue? Yes, from source inspection: current main marks Is this the best way to solve the issue? Yes, the patch is a narrow owner-boundary fix: classify side-effecting wrappers as policy-blocked before allowlist matching and pass the requested platform into command resolution. The remaining question is maintainer acceptance of the compatibility impact, not a different implementation path. AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against dc5954b0f8cb. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +82, Tests +96. Total +178 across 8 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
ClawSweeper PR egg ✨ Hatched: 🌱 uncommon Frosted Clawlet Hatch commandComment Hatchability rules:
Rarity: 🌱 uncommon. What is this egg doing here?
|
|
Updated the PR body with direct exec-approval allowlist probe output for the blocked wrapper cases and the still-allowed plain time case. @clawsweeper re-review |
|
🦞👀 Command router queued. I will update this comment with the next step. |
* fix: block side-effecting command wrappers * docs: add changelog entry for PR merge
…026.5.27) (#698) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/openclaw/openclaw](https://openclaw.ai) ([source](https://github.com/openclaw/openclaw)) | patch | `2026.5.26` → `2026.5.27` | --- ### Release Notes <details> <summary>openclaw/openclaw (ghcr.io/openclaw/openclaw)</summary> ### [`v2026.5.27`](https://github.com/openclaw/openclaw/blob/HEAD/CHANGELOG.md#2026527) [Compare Source](openclaw/openclaw@v2026.5.26...v2026.5.27) ##### Highlights - Safer local/runtime boundaries: OpenClaw now rejects unsafe command wrappers, malformed CLI numeric options, unsafe Node runtime env overrides, no-auth Tailscale exposure, and non-admin device-role pairing approvals before they can affect live runs. ([#​87308](openclaw/openclaw#87308), [#​87305](openclaw/openclaw#87305), [#​87292](openclaw/openclaw#87292), [#​87146](openclaw/openclaw#87146)) - Matrix and auto-reply delivery are steadier: mention previews stay inert, final mention replies deliver normally, shared-DM notices are awaited, MXID parsing ignores filenames, and reasoning-prefixed `NO_REPLY` responses stay suppressed. - Provider and agent reliability improved across OpenAI-compatible embeddings, cached token usage, Anthropic/Codex/Claude runtime state, unsupported tool-schema quarantine, heartbeat templates, and session fallback errors. ([#​85269](openclaw/openclaw#85269), [#​82062](openclaw/openclaw#82062), [#​85416](openclaw/openclaw#85416), [#​86855](openclaw/openclaw#86855)) - Plugin and package release paths got tighter: Pixverse ships as an external video plugin with region selection, package exclusions and shrinkwrap inventory match the published npm shape, and release/package smoke commands fail bounded instead of hanging. - Gateway hot paths do less rediscovery by reusing current plugin metadata fingerprints, stable plugin index fingerprints, read-only session metadata, active working stores, status fast paths, and auth/env snapshots. ([#​86439](openclaw/openclaw#86439)) ##### Changes - Memory: add a core OpenAI-compatible embedding provider for local and hosted OpenAI-style endpoints, with config, doctor, and docs support. ([#​85269](openclaw/openclaw#85269)) Thanks [@​dutifulbob](https://github.com/dutifulbob). - Plugin SDK: mark memory-specific embedding provider registration as deprecated compatibility and surface non-bundled usage in plugin compatibility diagnostics. ([#​85072](openclaw/openclaw#85072)) Thanks [@​mbelinky](https://github.com/mbelinky). - Pixverse: add video generation provider support, API region selection, and external plugin publishing. - Plugins: expose approval action metadata for plugin-driven approval surfaces. ##### Fixes - Security/CLI/runtime: harden hostname normalization for repeated trailing dots, block side-effecting command wrappers, reject unsafe Node runtime env overrides, reject loose numeric CLI and gateway options, require admin approval for node device-role pairing, and reject no-auth Tailscale exposure. ([#​87305](openclaw/openclaw#87305), [#​87292](openclaw/openclaw#87292), [#​87308](openclaw/openclaw#87308), [#​87146](openclaw/openclaw#87146)) Thanks [@​pgondhi987](https://github.com/pgondhi987). - Doctor: validate runtime tool schemas for every configured embedded agent while skipping ACP-only profiles, so bad non-default plugin or MCP tools are reported before assistant turns. - Telegram: route `sendMessage` action replies through durable outbound delivery so completed agent responses remain retryable when the gateway send path times out. ([#​87261](openclaw/openclaw#87261)) Thanks [@​mbelinky](https://github.com/mbelinky). - Matrix/auto-reply: keep draft previews mention-inert, preserve final mention delivery, send mention finals normally, await shared DM notices, ignore filename-embedded MXIDs, and suppress reasoning-prefixed `NO_REPLY` responses. - Agents/providers: add OpenAI-compatible cache retention, forward cached token usage in chat completions, preserve runtime context before active user turns, strip stale Anthropic thinking, load Claude CLI OAuth for Pi auth profiles, avoid false Codex runtime live switches, and quarantine unsupported tool schemas. ([#​82062](openclaw/openclaw#82062), [#​87167](openclaw/openclaw#87167), [#​86855](openclaw/openclaw#86855)) - Gateway/performance: cache plugin metadata fingerprints and stable plugin index fingerprints, borrow read-only session metadata safely, keep the active session working store hot, keep status on a bounded fast path, and preserve model auth profile suffixes. ([#​86439](openclaw/openclaw#86439)) - Package/install/release: align npm package exclusions and inventory, omit unpacked test helpers, skip Homebrew until macOS packages need it, cap tsdown heap in containers, bound install/release smoke waits, and harden post-publish verification. - Codex/Auth: bound ChatGPT OAuth token exchange and refresh requests, and honor cancellation across Codex and Anthropic OAuth login flows. - QA/E2E/CI: bound Telegram, kitchen-sink, Open WebUI, ClawHub, MCP, Discord, realtime, labeler, and GitHub API waits; fail empty explicit test, live-media, gateway CPU, startup benchmark, plugin gauntlet, and beta-smoke runs instead of false-greening. - Agents/Codex: keep spawned agent bootstrap files rooted in the agent workspace while running task commands, transcripts, and compaction from the requested cwd. ([#​87218](openclaw/openclaw#87218)) Thanks [@​mbelinky](https://github.com/mbelinky). </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/698
* fix: block side-effecting command wrappers * docs: add changelog entry for PR merge
* fix: block side-effecting command wrappers * docs: add changelog entry for PR merge
Summary
timeusage transparent when it only reports to stderr, while blocking output-file forms before allowlist matching.Linked context
No public issue linked in this PR body.
Real behavior proof (required for external PRs)
node scripts/run-vitest.mjs src/infra/exec-wrapper-resolution.test.ts src/infra/exec-command-resolution.test.ts src/infra/exec-approvals-analysis.test.tsnode --import tsx --input-type=modulewithevaluateShellAllowlistprobes forscript ~/.zshenv git log -1 --format='payload'ondarwin,/usr/bin/time -o ~/.bashrc -a -f 'payload' git statusonlinux, and/usr/bin/time -p git statusonlinux.Test Files 3 passed (3); Tests 269 passed (269)bsd-script-darwin {"analysisOk":true,"allowlistSatisfied":false,"segmentSatisfiedBy":[null],"policyBlocked":true,"blockedWrapper":"script"}gnu-time-output-linux {"analysisOk":true,"allowlistSatisfied":false,"segmentSatisfiedBy":[null],"policyBlocked":true,"blockedWrapper":"time"}gnu-time-stderr-linux {"analysisOk":true,"allowlistSatisfied":true,"segmentSatisfiedBy":["allowlist"],"policyBlocked":false}scripttranscript wrappers and GNUtime -owrappers are policy-blocked before allowlist matching; plaintime -premains allowlist-transparent.scripton a macOS/FreeBSD host.Tests and validation
Which commands did you run?
git diff --checkpnpm exec oxfmt --write src/infra/dispatch-wrapper-resolution.ts src/infra/exec-approvals-allowlist.ts src/infra/exec-approvals-analysis.ts src/infra/exec-wrapper-trust-plan.ts src/infra/exec-wrapper-resolution.test.ts src/infra/exec-command-resolution.test.ts src/infra/exec-approvals-analysis.test.tsnode scripts/run-vitest.mjs src/infra/exec-wrapper-resolution.test.ts src/infra/exec-command-resolution.test.ts src/infra/exec-approvals-analysis.test.tsnode --import tsx --input-type=moduledirectevaluateShellAllowlistprobes for the blockedscriptandtime -oforms plus allowedtime -p.What regression coverage was added or updated?
scripttranscript wrappers and GNUtime -o/--outputwrappers.gitallowlist while plaintime -pstill does.What failed before this fix, if known?
The wrapper allowlist behavior could approve the reduced inner command while execution preserved the raw wrapper command.
If no test was added, why not?
Not applicable.
Risk checklist
Did user-visible behavior change? (
Yes/No)Yes.
Did config, environment, or migration behavior change? (
Yes/No)No.
Did security, auth, secrets, network, or tool execution behavior change? (
Yes/No)Yes.
What is the highest-risk area?
Exec approval compatibility for users who intentionally wrapped allowlisted commands with transcript or output-file wrappers.
How is that risk mitigated?
The change is limited to wrapper policy transparency, preserves non-file-output
timebehavior, and adds focused regression coverage for blocked and still-transparent cases.Current review state
What is the next action?
Review gates and GitHub CI are pending.
What is still waiting on author, maintainer, CI, or external proof?
Maintainer review and GitHub CI are pending; direct real-behavior proof has been added above.
Which bot or reviewer comments were addressed?
ClawSweeper's real-behavior proof request was addressed by adding direct patched-code allowlist probe output to this PR body.