fix(security): pin ACP npx launchers to reviewed versions (closes #3357)#3399
Open
Sanjays2402 wants to merge 1 commit into
Open
fix(security): pin ACP npx launchers to reviewed versions (closes #3357)#3399Sanjays2402 wants to merge 1 commit into
Sanjays2402 wants to merge 1 commit into
Conversation
Closes OpenHands#3357. The three built-in ACP providers in openhands.sdk.settings.acp_providers launch with floating npx commands (`npx -y <pkg>`), which resolve npm's `latest` tag at agent-launch time — after commit review, after the uv lock's `exclude-newer` guardrail, and after the agent-server image build. Because each provider also defaults to a permission-disabling session mode (`bypassPermissions`, `full-access`, `yolo`), a poisoned or unexpectedly broken `latest` publish would be fetched and executed under a high-trust mode on the next launch. This change pins each launch command to the same versions the agent-server Dockerfile already installs at image build time (`@agentclientprotocol/claude-agent-acp@0.30.0`, `@zed-industries/codex-acp@0.11.1`, `@google/gemini-cli@0.39.1`), so build-time and runtime versions cannot diverge. The gemini-cli pin is bumped from 0.38.0 → 0.39.1 in both the SDK and the Dockerfile, matching the patched release called out in the issue. The versions are declared as module-level constants (`CLAUDE_AGENT_ACP_VERSION`, `CODEX_ACP_VERSION`, `GEMINI_CLI_VERSION`) so future bumps are one-line edits and the intent is documented inline. The OpenAPI example in `conversation_router_acp.py` is also fixed: it previously launched `npx -y claude-agent-acp` (unscoped, 404 on npm, registerable by anyone — a dependency-confusion footgun). It now matches the provider default. No public API change: the `default_command` tuple shape is unchanged, only its contents.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Closes #3357.
The three built-in ACP providers in
openhands.sdk.settings.acp_providerslaunch with floatingnpx -y <pkg>commands. That means the package version is resolved from npm at agent-launch time — after commit review, after the[tool.uv] exclude-newerguardrail on the Python lock, and after the agent-server image build that already pins these very packages. Each provider also defaults to a permission-disabling session mode (bypassPermissions,full-access,yolo), so a poisoned or unexpectedly brokenlatestpublish would be fetched and executed under a high-trust mode on the next launch.Hardening, not a report of an active exploit — the goal is to bring the npm ACP launchers under the same version discipline the repo already applies elsewhere.
Summary
default_commandforclaude-code,codex, andgemini-cliinopenhands-sdk/openhands/sdk/settings/acp_providers.pyto the versions the agent-server Dockerfile already installs (@agentclientprotocol/claude-agent-acp@0.30.0,@zed-industries/codex-acp@0.11.1,@google/gemini-cli@0.39.1). Pins are declared as module-level constants so future bumps are one-line edits.@google/gemini-clifrom0.38.0→0.39.1in both the SDK pin andopenhands-agent-server/openhands/agent_server/docker/Dockerfile, matching the patched release called out in the issue.openhands-agent-server/openhands/agent_server/conversation_router_acp.py:53— previously launchednpx -y claude-agent-acp(unscoped name, 404 on npm today, registerable by anyone → dependency-confusion footgun). Now matches the scoped, pinned provider default.tests/sdk/test_settings.pythat asserted the full defaultacp_commandlist. The two substring assertions intests/sdk/settings/test_acp_providers.pyalready usein, so they remain valid against the pinned commands.Issue Number
Closes #3357
How to Test
Or, by inspection:
The SDK-side pins and the Dockerfile-side pins for the bundled agent-server image are now identical, so build-time and runtime versions cannot diverge.
I was not able to run the test suite locally —
uv syncfailed on a transient disk-space issue in my dev environment, not the change. CI will exercise the targeted tests above; the changes are config-only and the diff is small and reviewable end-to-end.Video/Screenshots
N/A — no UI change.
Type
Notes
default_commandis a tuple ofstr; only its contents changed. Callers that build their own commands viaACPAgent(acp_command=[...])are unaffected.0.38.0 → 0.39.1) is the same delta the issue calls out as>= 0.39.1. Holding at0.39.1rather than chasing the currentlatest(0.43.0) keeps the SDK pin and Dockerfile pin tightly aligned with what's already been reviewed for the image.acp_providers.py(constants block) and the Dockerfilenpm install -gline. The constants block has a comment pointing at the Dockerfile to make that contract obvious.This PR was prepared by an AI agent (Cake, a Hermes agent running on @Sanjays2402's machine) on behalf of @Sanjays2402, who reviewed the diff before submission. The "A human has tested these changes" box is intentionally left unchecked because the test suite was not run locally end-to-end (disk-space issue in the dev environment); CI will verify.