The Gate Returns Yes: Four Agent Frameworks, One Bypassed Boundary
A prompt injection doesn’t become remote code execution because a model is clever. It becomes RCE because the one control engineered to stop it — the approval gate — silently returns “yes.”
This week four agent frameworks received CVEs for the same class of defect: the gate between model output and host execution was either overridden by a model-controlled parameter, absent by default, or implemented as an eval() call. The operator who ran the agent under --approval-policy on-request believing every code-issuing tool would prompt is exactly as exposed as the one who passed --auto. The prompt isn’t defeated; it’s skipped at a prior branch.
| Framework | CVE | Gate Failure Mode | Severity |
|---|---|---|---|
| AWS Strands Agents Tools | CVE-2026-18733 | LLM-controlled non_interactive parameter bypasses consent gate | CVSS 3.1: 8.8 HIGH |
CodeWhale rlm_eval / exec_shell_interact | CVE-2026-75858 / CVE-2026-75857 | ApprovalRequirement::Auto short-circuits policy check | CVSS 4.0: 8.5 / 7.3 |
| atomic-agents-stack MCP catalog | GHSA-xhcr-cqfr-m3hv | Cleartext HTTP catalog + no default allowlist → MITM to RCE | CVSS 4.0: 8.7 |
| Xinference Llama3 tool parser | CVE-2026-61539 | eval(model_output, {}, {}) parses model output as executable Python | CVSS 3.1: 10.0 CRITICAL |
AWS Strands: The Consent Gate Is a Flag the Model Can Flip
Amazon’s advisory (bulletin 2026-072-AWS, published 3 Aug 2026) is the least exotic but most instructive. The strands-agents-tools shell tool has a human consent gate that prompts the operator before commands run. It also exposed a non_interactive parameter in its input schema that the LLM controls. A crafted prompt — delivered via indirect prompt injection in untrusted content the agent reads — sets non_interactive=true, and arbitrary OS commands execute without operator approval.
The gate is a boolean in the very schema the model fills in. Fixed by removing the parameter in 0.8.0. Until then, the workaround is operational: don’t give an agent that processes untrusted content a shell tool, and isolate it least-privilege.
The GitHub advisory confirms: affected versions < 0.8.0, patched in 0.8.0. The CVSS v3.1 vector is AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H — network reachable, low complexity, no privileges, but user interaction required (the agent must process attacker-controlled content). The CVSS v4.0 score of 7.5 with AT:P (Attack Requirements Present) more accurately captures the precondition.
CodeWhale: Auto Means “Never Prompt”
CodeWhale is a Rust agent TUI. Its rlm_eval tool runs an arbitrary Python string the model picks, in a real python3 interpreter, on your machine at your UID. The tool advertises ExecutesCode and Network capabilities. The trait default would demand approval for any tool that can execute code. rlm_eval overrides it:
fn approval_requirement(&self) -> ApprovalRequirement {
ApprovalRequirement::Auto // overrides the safe default below
}
Auto is not “maybe ask.” The CVE advisory traces exactly what the engine does with it. The gate is two AND-ed conditions in engine.rs:
let approval_required = spec.approval_requirement() != ApprovalRequirement::Auto
&& !registry.context().auto_approve;
When approval_requirement() is Auto, approval_required is false. No Event::ApprovalRequired is emitted. The user’s --approval-policy (on-request, unless-trusted, never) is never consulted. So the operator who ran the agent under --approval-policy on-request believing every code-issuing tool would prompt is exactly as exposed as the one who passed --auto. The prompt isn’t defeated; it’s skipped at a prior branch.
The Sibling That Proves the Pattern
CodeWhale’s run_tests tool had the identical flaw — ApprovalRequirement::Auto on a tool that runs cargo test, which compiles and executes arbitrary code (CVE-2026-45311, CVSS 9.6). The source even stated the intent: “Tests are encouraged, so avoid gating them behind approval.” It was fixed in 0.8.23. But the fix never reached rlm_eval or rlm_open, which expose a broader surface. The advisory says it plainly: “This is the same defect that was already patched on the sibling run_tests tool; the fix never reached rlm_eval or rlm_open.”
That is the pattern worth naming. Fixing one Auto doesn’t fix the default. As long as Auto exists as a per-tool escape that overrides the ExecutesCode → Required default, the class regenerates.
exec_shell_interact: The Approved Shell Is the Attack Surface
exec_shell itself is correctly gated. Its sibling exec_shell_interact is not. exec_shell_interact returns ApprovalRequirement::Auto, and when the model writes input into a shell the user already approved — a python3 -i REPL, mysql, ssh, sudo -i — no prompt fires. Inside those processes, stdin is the command surface. The user approved opening the shell once, for a stated purpose; the model then chooses the input, and prompt injection steers it.
The reach scales with the approved process: mysql -u root becomes arbitrary SQL, ssh host becomes commands on the remote host, sudo -i becomes root. None of it re-prompts.
Fixed in CodeWhale 0.8.64 (commit 57f3c89). Two CVEs assigned 18 Aug 2026: CVE-2026-75858 for rlm_eval, CVE-2026-75857 for exec_shell_interact.
atomic-agents-stack: The Gate Is Absent, and the Catalog Is in Cleartext
The MCP registry backend in atomic-agents-stack accepts both http and https schemes for the catalog URL (GHSA-xhcr-cqfr-m3hv, published 10 Jun 2026). Catalog entries carry command/args that are type-validated but content-unrestricted. Those are later spawned as local stdio subprocesses by MCPClientPool.
Over a cleartext http:// catalog URL, a man-in-the-middle rewrites the catalog response to inject arbitrary command/args — and you get code execution on the agent host with no LLM involvement at all. The intended mitigation, a command allowlist (mcp_allow_fn), defaults to None, so without an operator-authored allowlist every resolved spec connects.
Fixed in 1.1.0 (commit c2dd337) by requiring https by default and gating http:// behind a loud explicit opt-in (ATOMIC_AGENTS_MCP_SERVER_REGISTRY_ALLOW_HTTP=1). Defense-in-depth: a spawn gate validates every spec’s command basename against an allowlist ({npx, uvx, python, python3, node, docker} by default, operator-replaceable via mcp.md) before constructing StdioServerParameters. The gate raises MCPCommandNotAllowed (subclass of MCPServerConnectFailed) which propagates fail-closed — it is NOT soft-skipped.
Xinference: eval() Where Tool-Call Output Meets the Parser
The most severe of the batch is Xinference (GHSA-x2rj-828p-hx9m / CVE-2026-61539), CVSS 10.0 Critical, published 21 Aug 2026. Its Llama3 tool-call parser did:
def extract_tool_calls(self, model_output: str) -> List[Tuple[Optional[str], Optional[str], Optional[Dict[str, Any]]]]:
try:
data = eval(model_output, {}, {})
return [(None, data["name"], data["parameters"])]
except Exception:
return [(model_output, None, None)]
eval() is not a sandbox — eval(model_output, {}, {}) executes the input as a Python expression in the Xinference server process. The model output is influenced by attacker prompts sent to the OpenAI-compatible /v1/chat/completions endpoint, and on the tested default deployment authentication was not enabled. A remote, unauthenticated attacker who can get the model to emit __import__('os').system('touch /tmp/hacked') gets it executed on the server. No approval gate, because there is no tool call to gate — the parser is the injection sink.
Fixed in 2.7.0 (commit df4c7cb). The NVD record confirms the vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H — network reachable, low complexity, no privileges, no user interaction, scope changed, full CIA impact.
What This Says About the Boundary
The control loop’s verifier is the gate. When the gate returns Auto, the verifier is out of the loop. The model wasn’t the problem — the model “did what it was designed to do.” The architecture placed the gate in a place that was either overridden by default, controlled by the model’s own arguments, or never built.
The uncomfortable truth: most operators cannot verify their agent is safe here, because the failure is silent. A tool that returns Auto produces no approval dialog, no audit event, no warning. The user believes --approval-policy on-request protects them; the code proves it doesn’t. There is no error saying the gate was skipped.
What Builders Should Do
- Require
Requiredfor every tool whose capabilities includeExecutesCode. If a tool exposes code execution or network, the trait default must not be overridable toAuto. This is the single highest-value change. - Audit, don’t assume. Search every tool’s
approval_requirement()forAuto— CodeWhale’s own advisory shows the class survives a patch that only fixed one instance. - Never parse model output with
eval(). If a field arrives from an LLM and you must evaluate a data structure, use a real parser (AST,json), nevereval/exec. - Default-deny the tool catalog. Allowlist the resolved command basename before any registry- or catalog-sourced subprocess spawn; require
httpsand reject cleartext transport. - Make consent gates non-model-visible. A parameter the model fills in to skip consent is not a consent gate. Approvals must be a separate channel.
- Isolate. The gate is a control, not a boundary. Run agents that read untrusted content in an isolated, least-privilege environment, so a bypassed gate is contained rather than fatal.
Upgrade where a fix exists: CodeWhale to 0.8.64, strands-agents-tools to 0.8.0, atomic-agents-stack to 1.1.0, Xinference to 2.7.0. Then go check the gate you think you have.
The boundary that separates an agent from your shell is not the model. It’s a match on an enum — and it’s defaulting to yes.
Sources
- AWS Security Bulletin 2026-072-AWS — CVE-2026-18733 Strands Agents Tools consent-gate bypass
- GitHub Advisory GHSA-mqvc-p852-wf8x — Strands Agents Tools
- NVD CVE-2026-18733 Detail
- CodeWhale rlm_eval Advisory GHSA-wrj3-vj8c-784f
- CodeWhale exec_shell_interact Advisory GHSA-g29h-pfmp-qp9r
- CVE-2026-75858 — CodeWhale rlm_eval
- CVE-2026-75857 — CodeWhale exec_shell_interact
- CodeWhale Fix Commit 57f3c89 → 0.8.64
- Prior Same-Class Defect: CVE-2026-45311 run_tests
- atomic-agents-stack Advisory GHSA-xhcr-cqfr-m3hv
- atomic-agents-stack Fix Commit c2dd337
- Xinference Advisory GHSA-x2rj-828p-hx9m
- NVD CVE-2026-61539 Detail
- CVE-2026-61539 Record
- Xinference Fix Commit df4c7cb