Skip to content

CVE catalog

This page is auto-generated from the regression tests in tests/cves/.

Every CVE listed here has a corresponding test that reproduces the vulnerable tool-call pattern and asserts an agent-airlock primitive blocks it. The suite is a second defence — upstream vendors have shipped fixes for every CVE below. Agent-airlock's job is to catch the same class of bug when a vulnerable server is still running, or when a new tool ships with the same shape.

See tests/cves/README.md for the classification rules and a list of CVEs we deliberately chose NOT to cover (transport-layer and web-framework bugs that sit outside the airlock execution seam).

To regenerate this page:

python3 scripts/gen_cve_catalog.py --write

CI runs python3 scripts/gen_cve_catalog.py --check on every PR, so the catalog and the tests stay in lockstep.

Summary

CVE Component / title CVSS Airlock fit
CVE-2025-59528 Flowise CustomMCP RCE via JS Function() constructor — —
CVE-2025-59536 Claude Code hooks RCE + MCP consent bypass (exfil leg) 8.7 (High) Partial
CVE-2025-68143 Anthropic mcp-server-git git_init path traversal 8.2 (High) Strong
CVE-2025-68144 Anthropic mcp-server-git argument injection 8.1 (High) Strongest
CVE-2025-68145 mcp-server-git --repository root not enforced 7.1 (High) Strong
CVE-2026-11393 AgentCore CLI triple-quote codegen RCE — —
CVE-2026-11624 MCP HTTP-transport Origin/Host DNS-rebinding 9.4 —
CVE-2026-19591 Codex command-safety parser disagreed with PowerShell about --% 8.8 (HIGH) — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H, CWE-150 Strong
CVE-2026-19753 mcp-rdf-explorer explore_url takes an attacker-supplied URL into SSRF 7.3 (HIGH) — CWE-918 Strong
CVE-2026-21520 Capsule ShareLeak / PipeLeak — —
CVE-2026-23744 MCPJam Inspector unauthenticated public bind 9.8 —
CVE-2026-25874 HuggingFace LeRobot pickle-deserialization RCE 9.3 —
CVE-2026-26118 Microsoft Azure MCP Server SSRF (IMDS token theft) 8.8 (High) Strong
CVE-2026-27825 mcp-atlassian arbitrary file write via download_path 9.1 (Critical) Strong
CVE-2026-27826 mcp-atlassian SSRF via X-Atlassian-*-Url headers 7.5 (High, AV:A/PR:N/UI:N, C:H) Partial
CVE-2026-30615 (Windsurf zero-click MCP config) — spawn-time config pin — —
CVE-2026-30616 MCP STDIO transport command-injection (Ox Security class) 9.8 (Critical) Strongest
CVE-2026-32625 (LibreChat MCP server-URL env-interpolation secret leak) 9.6 —
CVE-2026-33032 "MCPwn" — nginx-ui missing /mcp_message auth middleware 9.8 —
CVE-2026-39884 flux159/mcp-server-kubernetes argv injection — —
CVE-2026-40933 Flowise MCP-stdio adapter RCE regression 9.9 —
CVE-2026-41349 OpenClaw agentic consent-bypass 8.8 —
CVE-2026-41361 OpenClaw IPv6 SSRF guard bypass 7.1 —
CVE-2026-42271 CISA KEV regression fixture (LiteLLM MCP command injection) 3.1 —
CVE-2026-44211 Cline Kanban cross-origin WebSocket hijack 9.7 —
CVE-2026-47390 SSRF-protection bypass via alternate IP encodings — —
CVE-2026-48782 SafeURL IPv6-transition cloud-metadata SSRF bypass — —
CVE-2026-5023 codebase-mcp RepoMix OS command injection — —
CVE-2026-53710 ContextForge python_sandbox_server: RestrictedPython escape via raw getattr 10.0 (CRITICAL) — CWE-94 + CWE-693 Partial
CVE-2026-53820 OpenClaw exec-denylist bypass at MCP loopback spawn 6.9 —
CVE-2026-57124 PraisonAI UI /api/mcp/connect spawns caller-chosen local commands 9.8 (CRITICAL) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, CWE-306 + CWE-78 Partial
CVE-2026-6980 GitPilot-MCP repo_path injection — —
CVE-2026-75062 Google langfun lf.query evaluates model-generated Python unsandboxed 9.2 (CRITICAL) — CWE-95, CWE-1188 Partial
CVE-2026-75130 Upstash Context7 "ContextCrush" MCP instruction injection 9.0 (Critical, CVSS v3.1; NVD also records 6.4 Medium under v4.0) Strongest
CVE-2026-77521 MaxKB SandboxShellBackend exposes an unapproved execute shell tool 10.0 (CRITICAL) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H Partial
CVE-2026-78575 IBM Langflow MCP stdio server config takes unvalidated command-line arguments 8.8 (HIGH) — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H, CWE-78 Partial
CVE-2026-79748 MCPHub server-config endpoints spawn attacker-supplied stdio commands 9.9 (CRITICAL) — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H, CWE-862 Partial
CVE-2026-90898 Bifrost MCP client registration spawns an unauthenticated stdio command 9.8 (CRITICAL) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, CWE-284 + CWE-306 Partial

Details

CVE-2025-59528

Flowise CustomMCP RCE via JS Function() constructor

Vulnerability

Flowise's /api/v1/node-load-method/customMCP passed user-supplied strings directly into JavaScript Function() and eval. CVSS 10.0. Patched in v3.0.6 (Sept 2025) but CSA documented active exploitation in April 2026 — ~12-15K instances still exposed. This regression codifies the offending token set (Function(, new Function, eval(, Deno.eval, vm.runInNewContext) so

CVE-2025-59536

Claude Code hooks RCE + MCP consent bypass (exfil leg)

Vulnerability

Claude Code (< 1.0.111) executes repository-controlled configuration — project hooks, registered MCP servers, and environment variables including ANTHROPIC_BASE_URL — BEFORE showing the user the trust dialog. Opening a malicious repository is therefore enough to (1) run arbitrary shell commands via hooks, and (2) redirect the agent's base URL to an attacker-controlled host that exfiltrates the API key on the first request.

Airlock mitigation

The hook-execution leg runs on the Claude Code client before any tool call exists, so runtime middleware has no seam. That half is out-of-scope for agent-airlock and is fixed by upgrading Claude Code.

The exfiltration leg — sending the API key to an attacker-controlled ANTHROPIC_BASE_URL — IS blockable. EndpointPolicy rejects any hostname not in the caller's allow-list, and SafeURL applies the same guard at the tool-signature level. If the agent's outbound requests are routed through an airlock-wrapped HTTP tool, the attempt to post to https://evil.example.com/... never leaves the process.

CVE-2025-68143

Anthropic mcp-server-git git_init path traversal

Vulnerability

The git_init tool of anthropics/mcp-server-git (< 2025.9.25 / 2025.12.18) accepts an arbitrary filesystem path as its repo_path argument without validating it against the configured repository root. An attacker who can prompt-inject the agent can therefore initialise a .git directory anywhere the server process can write, and — chained with a filesystem MCP — drop a malicious .git/config that achieves RCE on the next git invocation.

Airlock mitigation

This is the canonical SafePath / FilesystemPolicy defense. The fix upstream and the fix here are the same: reject any repo_path that escapes the configured repo root via os.path.commonpath().

We assert both: 1. SafePathValidator with the bare defaults rejects traversal strings (the pre-normalisation defense). 2. FilesystemPolicy.validate_path rejects paths outside the allowed root even when the path is syntactically clean (the post-resolution defense).

CVE-2025-68144

Anthropic mcp-server-git argument injection

Vulnerability

git_diff / git_checkout in anthropics/mcp-server-git (< 2025.12.18) pass user-controlled refs directly to the git CLI. A ref value starting with a hyphen (for example --output=/etc/profile.d/rce.sh) is interpreted by git as an OPTION rather than a ref, allowing arbitrary file overwrite through the resulting git subprocess call.

Airlock mitigation

The ghost/strict argument validator is exactly the primitive for "LLM passes a string that looks like a flag into a typed parameter." A Pydantic-strict model with a custom validator that rejects any ref beginning with - is a one-liner at the tool-decoration layer.

CVE-2025-68145

mcp-server-git --repository root not enforced

Vulnerability

When anthropics/mcp-server-git (< 2025.12.18) is started with the --repository flag to declare an allowed repo root, the server fails to verify on each subsequent tool call that the repo_path argument stays inside that root. A crafted argument such as /var/lib/otheruser/.git lets the server operate on any repo the process user can read.

Airlock mitigation

FilesystemPolicy with an allowed_roots list is the canonical mitigation. validate_path uses os.path.commonpath() (not string prefix) so it catches the three common escape variants:

  • absolute path outside the root
  • relative path with .. that would normalise outside the root
  • a symlink that points outside the root

CVE-2026-11393

AgentCore CLI triple-quote codegen RCE

Vulnerability

AWS AgentCore CLI < 0.14.2 (CVSS 9, CWE-94, published 2026-06-08) generates Python source by interpolating a model-/user-controlled collaborationInstruction into a code string without neutralising triple-quote characters. A crafted instruction containing """ closes the generated literal and injects statements that execute when another account user imports the agent — RCE on the AgentCore Runtime

CVE-2026-11624

MCP HTTP-transport Origin/Host DNS-rebinding

Vulnerability

Google MCP Toolbox for Databases < 0.25.0 (CWE-346 Origin Validation Error, CVSS 9.4): the MCP server exposed an HTTP/SSE transport that did not validate the Origin (or Host) header, so a browser the developer visits can DNS-rebind to 127.0.0.1 and script MCP tool calls at the local server (file reads, command execution, database access). Fixed in 0.25.0 with an --allowed-hosts flag alongside --allowed-origins, warning when

CVE-2026-19591

Codex command-safety parser disagreed with PowerShell about --%

Vulnerability

The OpenAI Codex CLI and Codex Desktop misclassified certain PowerShell commands as safe because their command-safety parser interpreted PowerShell's stop-parsing token (--%) differently than PowerShell itself. A user opening an attacker-prepared repository could have Codex run a file-writing Git command without requesting approval. If the write lands, it can modify Codex's own configuration; if Codex later loads that configuration it launches an attacker-controlled MCP server and executes code as the user. Upstream's fix does not add --% to a denylist of characters — it treats stop-parsing forms as unsupported in the AST-backed command flattener and routes them to the conservative path.

Airlock mitigation

This is not a new guard. It is the failure mode :class:~agent_airlock.mcp_spec.stdio_command_injection_guard.StdioCommandInjectionGuard already exists to prevent — a safety decision taken over an argv model that does not match what the shell will actually build — and the guard was missing the token that breaks the model. v0.8.89 adds it.

The interesting part is why a metachar list was the wrong shape for the fix, and these tests pin that:

  1. Whole-element, never substring. --% is PowerShell's stop-parsing token only when it stands alone. Folding it into DEFAULT_SHELL_METACHARS would have used substring matching and denied ordinary arguments like date +--%Y — noise, with no attack blocked in exchange.
  2. Checked before the metachar walk. After the token, the rest of the argv goes to the native command verbatim. A metachar verdict over those elements is an answer about a command line PowerShell will not construct. The token has to short-circuit, and the negative control below asserts it does: a payload carrying both a stop-parsing token and a shell metachar must report the token, not the metachar.

The guard does not and cannot fix Codex. What it does is refuse the same class of argv at the tool-call boundary, so an agent routed through airlock does not inherit its own parser's disagreement with the shell.

CVE-2026-19753

mcp-rdf-explorer explore_url takes an attacker-supplied URL into SSRF

Vulnerability

"A vulnerability was detected in Model Context Protocol mcp-rdf-explorer 1.0.0. Affected is the function explore_url of the file src/index.ts. Executing manipulation of the argument url can lead to server-side request forgery."

Airlock mitigation

The defect is carried in a tool argument the caller supplies, named in the advisory, reaching an outbound fetch. That is the seam SSRFEgressGuard sits on, and the guard refuses cloud metadata, loopback, link-local and IPv4-mapped-IPv6 targets while admitting a real SPARQL endpoint.

CVE-2026-21520

Capsule ShareLeak / PipeLeak

Vulnerability

Pins the deny-by-default + denied-exfil-sinks + reauth-on-untrusted posture of :func:capsule_indirect_injection_cve_2026_21520_defaults end-to-end: - Eagerly-constructed defaults are byte-identical to a fresh factory call. - Empty allowed_tools denies any read-side call (default_deny). - Every canonical exfil sink in the bundle is denied by name AND by glob.

CVE-2026-23744

MCPJam Inspector unauthenticated public bind

Vulnerability

Primary source (cited per v0.5.1+ convention): - GHSA-232v-j27c-5pp6 / CVE-2026-23744 (CVSS 9.8, fixed 1.4.3): https://github.com/advisories/GHSA-232v-j27c-5pp6

CVE-2026-25874

HuggingFace LeRobot pickle-deserialization RCE

Vulnerability

LeRobot's async-inference PolicyServer / robot-client call pickle.loads() on payloads received over an unauthenticated, non-TLS gRPC channel (SendObservations / SendPolicyInstructions / GetActions). An unauthenticated, network-reachable attacker reaches arbitrary OS command execution by sending a crafted pickle blob (CVSS 9.3, published 2026-04-23, unpatched as of disclosure).

CVE-2026-26118

Microsoft Azure MCP Server SSRF (IMDS token theft)

Vulnerability

Azure MCP Server Tools (< 2.0.0-beta.17) fetch URLs passed through tool arguments without validating the destination. A crafted argument of http://169.254.169.254/metadata/identity/oauth2/token?... causes the server process to hit the Azure Instance Metadata Service and return the managed-identity access token to the caller — trivially escalating any prompt-injection bug into full Azure resource takeover.

Airlock mitigation

validate_endpoint(...) rejects: - all four cloud-metadata hosts in _METADATA_HOSTS (169.254.169.254 / 253 / fd00:ec2::254 / metadata.google.internal), - any hostname that resolves to a private / loopback / link-local IP when allow_private_ips=False (the default), - any hostname matching a caller-supplied blocklist pattern.

CVE-2026-27825

mcp-atlassian arbitrary file write via download_path

Vulnerability

mcp-atlassian (< 0.17.0) exposes a confluence_download_attachment tool with a download_path argument. The tool writes the downloaded file to the provided path without boundary enforcement. An attacker who can prompt-inject the argument can therefore overwrite ~/.ssh/authorized_keys, ~/.bashrc, or any other file the server process can reach — and on the exposed HTTP transport deployment this requires no authentication.

Airlock mitigation

SafePath + FilesystemPolicy.allowed_roots is the textbook mitigation. The upstream fix (in 0.17.0) introduces a validate_safe_path function — agent-airlock has had this since v0.3.0.

CVE-2026-27826

mcp-atlassian SSRF via X-Atlassian-*-Url headers

Vulnerability

mcp-atlassian (< 0.17.0) uses unvalidated X-Atlassian-Jira-Url and X-Atlassian-Confluence-Url request headers to decide where to send upstream API calls. An attacker can redirect outbound requests to the IMDS endpoint or to an internal host to steal credentials or fingerprint the internal network.

Airlock mitigation

The vulnerability is at the HTTP-transport layer — headers aren't tool-call arguments. Runtime middleware cannot validate a header on an incoming request that never invokes a decorated tool.

BUT: when an MCP server is fronted by agent-airlock and the base URL is surfaced as a tool parameter (the common operator pattern these days — per-call URL selection instead of a static config), the same SafeURL + EndpointPolicy primitives that block CVE-2026-26118 block this too. That narrower case is what we assert here.

For the transport-header path, operators should (a) upgrade mcp-atlassian to ≥ 0.17.0 and (b) front their MCP server with an HTTP reverse proxy that strips or validates these headers before they reach application code.

CVE-2026-30615

(Windsurf zero-click MCP config) — spawn-time config pin

Vulnerability

Companion to test_cve_2026_30615_zero_click.py (which covers the config-file diff guard). This suite covers the spawn-time half: the mcp_config_pin preset / :class:McpConfigPinSet, which fingerprints the resolved STDIO spawn config at invocation time and fails closed (raises, never warns) on an injected or mutated server — catching the zero-click pattern even when the mutation never touched a watched config file.

CVE-2026-30616

MCP STDIO transport command-injection (Ox Security class)

Vulnerability

The MCP STDIO transport, implemented in the official Anthropic MCP SDKs across Python, TypeScript, Java, and Rust, passes the command and args fields of a client's STDIO server entry directly to a subprocess without validation, sanitisation, or sandboxing. The subprocess is spawned BEFORE the MCP handshake completes — so if the attacker controls the payload, the OS-level command runs whether or not the "server" ever returns a valid handshake. Ox catalogued four attack classes:

1. Unauthenticated command injection via a poisoned
   ``mcp.json`` / ``claude_desktop_config.json`` / ``.cursor``
   entry.
2. Authenticated command injection via a trusted-but-vulnerable
   MCP server that forwards user-controlled strings into a new
   STDIO invocation.
3. Zero-click prompt-injection chains across Claude Code,
   Cursor, Gemini-CLI, Windsurf, and GitHub Copilot — the agent
   writes a config entry on the attacker's behalf.
4. Config-file takeover — an attacker who can write to
   ``~/.cursor`` or the Claude Desktop config directory owns
   the machine on next launch.

Tenable has CVE-2026-30616 live against Jaaz 1.0.30 as one instance of this class. Ox documents 30+ affected open-source projects (LangChain-ChatChat, Agent Zero, LibreChat, MaxKB, WeKnora, Flowise, MCPJam Inspector, and more), and estimates ~200,000 vulnerable server instances across the ecosystem.

Airlock mitigation

The root cause is "the STDIO transport runs arbitrary OS commands with no policy layer in front of it." That is precisely the seam agent-airlock was designed to fill.

Anthropic's public position (per The Register, 2026-04-16) is that input sanitisation is the application author's responsibility and that STDIO behaviour is "expected." Agent-airlock is the Anthropic-side answer to that: a deny-by-default, in-process middleware that sits between the tool call and the subprocess.

We assert: 1. SecurityPolicy with an explicit tool allow-list blocks any call to an out-of-list tool (stops attack class 1 at the configuration seam — if spawn_stdio_server or equivalent is not in the allow-list, the payload never reaches execve). 2. UnknownArgsMode.BLOCK rejects ghost / LLM-invented arguments on a known tool (stops attack class 2, where the model was talked into inventing a malicious env or args field). 3. SafePath rejects a config-path traversal that would let the attacker write a poisoned entry into ~/.cursor or Claude Desktop's config directory (stops attack class 4).

Attack class 3 (prompt-injection of the chat UI) is a client-surface problem and out-of-scope for runtime middleware; see docs/cves/index.md fit-matrix notes.

CVE-2026-32625

(LibreChat MCP server-URL env-interpolation secret leak)

Vulnerability

LibreChat ≤ 0.8.3 (CVSS 9.6, CWE-200, published 2026-06-02) resolves ${VAR} placeholders in a user-supplied MCP server URL against the host process.env during schema validation, so an authenticated user exfiltrates server-side secrets (JWT_SECRET / CREDS_KEY / MONGO_URI) by embedding them in a URL that dials an attacker host. Patched in 0.8.4-rc1.

CVE-2026-33032

"MCPwn" — nginx-ui missing /mcp_message auth middleware

Vulnerability

letting unauthenticated clients invoke 12 destructive MCP tools. CVSS 9.8, ~2,689 exposed instances, actively exploited in April 2026.

agent-airlock doesn't ship nginx-ui, but we're the canonical place for the "would my MCPProxyGuard have caught a missing-auth on a destructive tool?" question. This module proves the preset fires on the exact nginx-ui tool inventory and on an IP-allowlist-only bypass attempt.

Primary sources

  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-33032
  • Rapid7 ETR (2026-04-15): https://www.rapid7.com/blog/post/etr-cve-2026-33032-nginx-ui-missing-mcp-authentication/

CVE-2026-39884

flux159/mcp-server-kubernetes argv injection

Vulnerability

Primary source (cited per v0.5.1+ convention): - https://www.sentinelone.com/vulnerability-database/cve-2026-39884/ (2026-04-14, fixed in 3.5.0) - https://nvd.nist.gov/vuln/detail/CVE-2026-39884

CVE-2026-40933

Flowise MCP-stdio adapter RCE regression

Vulnerability

Flowise <= 3.0.x lets an authenticated user define a CustomMCP server with the stdio transport, supplying an arbitrary command + args that Flowise serialises straight into a child-process spawn on the server — no sandbox, no argv sanitisation. CVSS 9.9. Fixed upstream in Flowise 3.1.0. This regression pins the agent-airlock-side control:

CVE-2026-41349

OpenClaw agentic consent-bypass

Vulnerability

Primary source (cited per v0.5.1+ convention): - https://www.thehackerwire.com/vulnerability/CVE-2026-41349/ (CVSS 8.8, disclosed 2026-04-23). The fix surface is :meth:SecurityPolicy.freeze + :meth:SecurityPolicy.verify_frozen, plus the openclaw_cve_2026_41349_defaults() preset that returns a frozen

CVE-2026-41361

OpenClaw IPv6 SSRF guard bypass

Vulnerability

Primary source (cited per v0.5.1+ convention): - https://www.redpacketsecurity.com/cve-alert-cve-2026-41361-openclaw-openclaw/ (CVSS 7.1, disclosed 2026-04-23). The bypass was that OpenClaw's IPv6 guard covered only the four canonical ranges (::/128, ::1/128, fe80::/10, fc00::/7) and left IPv4-mapped / NAT64 / 6to4 / documentation ranges routable.

CVE-2026-42271

CISA KEV regression fixture (LiteLLM MCP command injection)

Vulnerability

This complements test_cve_2026_42271_mcp_subprocess_arg.py (which unit-tests the guard's internals) by reproducing the actual HTTP request-body shape of the two affected LiteLLM endpoints and proving the deny-by-default preset blocks it end-to-end. It is a credibility-proof of existing coverage of an actively-exploited KEV CVE — not a new guard. NVD verbatim (https://nvd.nist.gov/vuln/detail/CVE-2026-42271, retrieved

CVE-2026-44211

Cline Kanban cross-origin WebSocket hijack

Vulnerability

Cline Kanban server (npm kanban < 2.13.0, CVSS 9.7, CWE-1385 + CWE-306, published 2026-06): the agent's control WebSocket server on 127.0.0.1:3484 accepts every upgrade without validating the Origin header. Because browsers do not apply same-origin/CORS to ws://, any website the developer visits can open a WebSocket to the loopback control server and drive the agent (leak workspace data, inject prompts → RCE, kill

CVE-2026-47390

SSRF-protection bypass via alternate IP encodings

Vulnerability

CWE-918: an agent egress filter that validates the literal hostname string of an outbound URL — rather than the resolved IP — is bypassed by encoding a loopback / link-local / cloud-metadata address in a form ipaddress rejects but socket.inet_aton (and the HTTP client / kernel) resolves straight back to an internal address, or by DNS rebinding. This suite pins, per the brief:

CVE-2026-48782

SafeURL IPv6-transition cloud-metadata SSRF bypass

Vulnerability

pydantic-ai 1.56.0–1.101.0 / 2.0.0b1–b2 (CWE-918 SSRF): the cloud-metadata blocklist compared the hostname string, so encoding the metadata IP 169.254.169.254 in an IPv6-transition form (IPv4-mapped, IPv4-compatible, 6to4, Teredo) or as a decimal/octal/hex integer slipped past it while the HTTP client still connected to the metadata endpoint — exposing cloud IAM credentials. This is an incomplete-fix follow-up to CVE-2026-46678 (which

CVE-2026-5023

codebase-mcp RepoMix OS command injection

Vulnerability

Primary source (cited per v0.5.1+ convention): - https://www.sentinelone.com/vulnerability-database/cve-2026-5023/ (unpatched upstream as of 2026-04-24). The package codebase-mcp wrapped the RepoMix CLI and shelled out with user-controlled paths across four handlers. This preset refuses to run those handlers unless the caller explicitly opts into

CVE-2026-53710

ContextForge python_sandbox_server: RestrictedPython escape via raw getattr

Vulnerability

Prior to 1.0.2, the python_sandbox_server sub-project exposes raw getattr through safe_builtins, bypassing RestrictedPython's _getattr_ mediation, and its validate_code pre-check searches for literal dangerous dunder strings. The advisory's proof of concept therefore builds those dunder names at runtime, walks the Python class hierarchy through the exposed getattr, reaches subprocess.Popen and runs an OS command. Its transcript records the decisive line: validation={'valid': True, 'message': 'Code passed validation'} followed by success=True — the code passed the sandbox's own check and then escaped it. Fixed in 1.0.2.

Airlock mitigation

Three compounding weaknesses in the advisory, and agent-airlock reaches one, per the split in docs/cve-triage.md.

Out of scope: weakness 3, "The execute_code MCP tool can be exposed over HTTP/SSE transport with no authentication layer." Same documented shape as CVE-2026-33032 and CVE-2026-23744. Also out of scope is the repair itself — removing getattr from someone else's safe_builtins is upstream's 1.0.2, not something a contract layer can express.

In scope: the primitive. A caller-supplied code argument carrying a payload that reaches an interpreter sink is the documented in-scope shape (docs/cve-triage.md, "Code injection into an interpreter sink"), and getattr is already in :data:DEFAULT_EVAL_SINKS. So this is a second-defence regression fixture against an existing guard, not a new guard — the CVE-2026-90898 / CVE-2026-57124 pattern.

CVE-2026-53820

OpenClaw exec-denylist bypass at MCP loopback spawn

Vulnerability

OpenClaw < 2026.5.12 (exec-denylist bypass, CVSS 6.9, CWE-693 Protection Mechanism Failure): the bundled MCP loopback session-spawn path let an authenticated caller reach a denylisted command because the surface command checked against the exec restriction differs from the effective command actually spawned — a name that passes the surface check resolves, via an alias / wrapper binary / shell, to a denied executable.

CVE-2026-57124

PraisonAI UI /api/mcp/connect spawns caller-chosen local commands

Vulnerability

Prior to 4.6.59 the default PraisonAI UI host applications expose POST /api/mcp/connect without mandatory authentication and accept caller-controlled command and args values, which PraisonAIUI passes to StdioMCPClient to start a local process. The UI commands (praisonai ui, praisonai ui agents, praisonai claw) bind to 0.0.0.0 by default, so a reachable unauthenticated client executes commands as the UI service account. The advisory's own proof of concept records the decisive detail: the spawned touch marker file exists even though the MCP handshake then fails with Connection failed — the process starts before anything validates that this is really an MCP server. Fixed in 4.6.59.

Airlock mitigation

Two halves, and agent-airlock reaches exactly one of them, per the split in docs/cve-triage.md.

The missing authentication on the route, and the 0.0.0.0 bind, are out of scope — the documented shape, the same class as CVE-2026-33032 and CVE-2026-23744. Nothing here can require a credential on someone else's endpoint, and the upstream fix in 4.6.59 is the correct layer for it.

What is reachable is the primitive: command and args arriving flat in a request body and heading for a stdio spawn. That is the CVE-2026-42271 shape, so this is a second-defence regression fixture against an existing guard, not a new guard.

The handshake detail is what makes an argument-level guard the right second defence rather than a redundant one. Because the process starts before the MCP handshake is validated, a defence that waits for a well-formed MCP session is already too late; the refusal has to happen on the registration argument itself.

CVE-2026-6980

GitPilot-MCP repo_path injection

Vulnerability

Primary source (cited per v0.5.1+ convention): - RedPacket Security CVE alert (2026-04-25): https://www.redpacketsecurity.com/cve-alert-cve-2026-6980-divyanshu-hash-gitpilot-mcp/ - vulnerability.circl.lu Vendor unresponsive; project does not version. Preset matches by tool-name regex only.

CVE-2026-75062

Google langfun lf.query evaluates model-generated Python unsandboxed

Vulnerability

"Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection') in the default lf.query Python protocol in Google langfun versions prior to 0.1.2 allows remote unauthenticated attackers to execute arbitrary Python code in the context of the host application via crafted prompt inputs that cause the model to generate executable Python expressions evaluated without a sandbox."

Airlock mitigation

This is the exploitation class EvalRCEGuard's own docstring names — "a model-derived string reaches a Python runtime evaluator" — and the guard refuses the disclosed payload shapes while admitting the arithmetic the protocol exists to evaluate.

It is partial for a reason worth stating rather than burying. The defect is that langfun calls an evaluator on model output at all; the sandbox is missing inside langfun, not at a tool-call boundary. agent-airlock only sees this if the generated expression passes through an airlocked tool argument. Where it does, the guard refuses it. Where langfun evaluates internally, nothing in this library is on the path, and no arrangement of presets changes that — upgrade to langfun 0.1.2.

So this fixture pins the primitive, not the patch: if a model-generated expression carrying an eval sink reaches a guarded argument, it is refused.

CVE-2026-75130

Upstash Context7 "ContextCrush" MCP instruction injection

Vulnerability

Context7 through 2.1.2 serves a per-library Custom AI Instructions ("Custom Rules") field through its MCP server without sanitising it. An attacker registers a library in the public Context7 registry and embeds instructions in that field; when any developer later asks their coding agent about that library, the text is inserted directly into the model's working context as though it were documentation. No user interaction with the attacker is required beyond a routine documentation request.

Noma Security's proof of concept chained three legs through the connected agent's own, already-authorised tools:

1. Search the workspace for ``.env`` files and read them.
2. File the contents as a **GitHub issue** on an attacker-owned
   repository.
3. Delete local folders on the victim's machine.

NVD records two very different scores. v3.1 rates it 9.0 Critical. v4.0 rates it 6.4 Medium — because it scores VC:N/VI:N/VA:N with SC:H/SI:H/SA:H: Context7 itself is unharmed and the entire impact lands on the connected downstream system. That gap is not a disagreement about how bad this is; it is an accurate description of the class, and the reason a server-side fix does not protect an agent talking to some other poisoned source. Upstash accepted the findings and shipped rule sanitisation with guardrails to production within days.

Airlock mitigation

Nothing in the chain crosses a network boundary the agent was not already authorised to cross. The agent may read files. It may call the GitHub tool. It may delete. Every individual call is in-policy for an authenticated principal — what is wrong is the arguments: a .env path nobody asked for, an issue body full of credentials, a delete nobody requested. A transport or identity layer sees three authorised calls and has nothing to object to. That is an argument-level failure, which is the seam this library exists to cover.

CVE-2026-77521

MaxKB SandboxShellBackend exposes an unapproved execute shell tool

Vulnerability

Prior to 2.10.5-lts, MaxKB assistants carrying a tool, MCP tool, skill or sub-application use SandboxShellBackend, which "exposes an execute shell tool without excluding it and omits execute from interrupt_on, so human approval is not required. Untrusted chat or ingested content can therefore cause command execution; source deployments with MAXKB_SANDBOX disabled run commands directly as the application user, while the official root container's string-based gosu wrapper allowed shell metacharacters to execute outside the intended sandbox." Fixed in 2.10.5-lts.

Airlock mitigation

Three weaknesses compound here and agent-airlock reaches one, per the split in docs/cve-triage.md.

Out of scope: the exposure and the approval gate. execute being offered at all (CWE-749) and being absent from interrupt_on (CWE-250) are decisions in MaxKB's own assistant configuration. agent-airlock ships the primitives that express both — SecurityPolicy(allowed_tools=...) for least privilege and PolicyEscalation / Approver for a human gate — but they are a posture an operator adopts for their own tools. Nothing in a contract layer can impose an approval step on someone else's agent backend, and 2.10.5-lts is the right place for it.

In scope: the primitive. Shell metacharacters riding in a caller-controlled command string is the documented in-scope shape (docs/cve-triage.md, "Metacharacter / escape neutralisation mismatch", anchored on CVE-2026-19591), and StdioCommandInjectionGuard already refuses it. So this is a second-defence regression fixture against an existing guard, not a new guard — the CVE-2026-90898 / CVE-2026-57124 pattern.

CVE-2026-78575

IBM Langflow MCP stdio server config takes unvalidated command-line arguments

Vulnerability

IBM Langflow OSS 1.0.0 through 1.11.5 "could allow a remote authenticated attacker to execute arbitrary commands due to improper validation of command-line arguments in the MCP stdio server configuration."

Its sibling CVE-2026-81941 (same bulletin, CWE-284, also CVSS 8.8) is the authorization half: an authenticated non-administrative user can build a flow whose MCP Tools component uses the local stdio subprocess transport, bypassing both LANGFLOW_CUSTOM_COMPONENT_ADMIN_ONLY and LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS — the two server-side controls meant to prevent exactly this.

Airlock mitigation

Same split as CVE-2026-79748 (MCPHub). Nothing here can restore Langflow's admin-only flag — that is CVE-2026-81941's half, it lives in Langflow's authorization layer, and this fixture does not pretend to reach it.

What is reachable is the primitive the missing check hands over: an attacker-controlled stdio command / args pair heading for a subprocess spawn. That is the shape agent-airlock already refuses for CVE-2026-40933 (Flowise) and CVE-2026-42271 (LiteLLM).

The reason this file exists rather than being folded into those: neither stdio guard covers this CVE on its own, and they fail in opposite directions. Measured, not assumed:

============================ ====================== ====================== payload metachar guard allowlist guard ============================ ====================== ====================== uvx ... "x.json; rm -rf /" blocks allows (cmd allowlisted) /bin/bash -c id allows (no metachar) blocks python -c "__import__..." allows (no metachar) blocks ============================ ====================== ======================

StdioCommandInjectionGuard is a shell-metacharacter detector, so an interpreter flag carries a payload straight past it — and that is precisely the shape Langflow's bulletin describes. McpSubprocessArgInjectionGuard allowlists the command, so once a launcher is allowlisted a metacharacter riding in its arguments goes through.

Run together they cover every disclosed shape and still admit the legitimate component, which test_running_both_guards_covers_every_disclosed_shape asserts end to end. That is a composition requirement rather than a bug in either guard, and it is pinned here so the pairing cannot be dropped from a preset on the belief that one is redundant.

CVE-2026-79748

MCPHub server-config endpoints spawn attacker-supplied stdio commands

Vulnerability

MCPHub before 0.12.15 exposes POST /api/servers and PUT /api/servers/:name, which create or update an MCP server configuration and then immediately spawn the configured stdio process via child_process.spawn. Authentication is required, but no authorization check restricts the endpoints to admins, and neither the command nor the args field is allowlisted or sanitised. Any authenticated non-admin user can therefore submit a configuration with command: "/bin/sh" and arbitrary args and execute it as MCPHub's OS user — commonly root in the published Docker image and in npx / systemd deployments. Fixed in 0.12.15 (PR #770).

Airlock mitigation

This CVE has two halves and agent-airlock reaches exactly one of them.

The assigned weakness is CWE-862 Missing Authorization — the same class as CVE-2026-33032 (nginx-ui) and CVE-2026-23744 (mcpjam), both of which are listed out-of-scope in tests/cves/README.md. Nothing in this library can add an admin check to an HTTP route that never calls into it, and this fixture does not pretend otherwise.

What is reachable is the primitive the missing check hands the attacker: a request-controlled stdio spawn config (command / args / env) arriving at a child_process.spawn sink. That is byte-for-byte the shape :class:~agent_airlock.mcp_spec.subprocess_arg_guard.McpSubprocessArgInjectionGuard already refuses for the KEV-listed CVE-2026-42271, so this is a second-defence regression fixture against an existing guard, not a new guard. A deployment that routes its spawn configs through the guard survives the authorization hole; one that does not, does not.

Per docs/cve-triage.md: where the CVE's class and its primitive split, the primitive decides whether a second-defence test is worth adding. This is that case, written down.

CVE-2026-90898

Bifrost MCP client registration spawns an unauthenticated stdio command

Vulnerability

Bifrost registers MCP clients through its management API. A stdio client is a command plus args, and Bifrost starts that program the moment the client is added — no MCP handshake required. The shipped default is governance.auth_config.is_enabled=false, and with auth off every caller is treated as a local admin, so a single unauthenticated POST /api/mcp/client runs a program as the Bifrost process user (appuser on the official image). transports/v2.1.0 refuses an unauthenticated stdio registration with 403; transports/v2.0.0 still allows it.

Airlock mitigation

Two halves, and agent-airlock reaches exactly one of them. This is the split docs/cve-triage.md describes, and it cuts the opposite way from CVE-2026-90617, which was dispositioned out of scope because its argument carried a natural-language prompt rather than a command.

The assigned weakness is CWE-306 Missing Authentication (with CWE-284 Improper Access Control) — the documented out-of-scope shape, the same class as CVE-2026-33032 and CVE-2026-23744. Nothing here can put an auth check on someone else's management route, and this fixture does not pretend to. The upstream fix is a 403 in the handler, which is the correct layer.

What is reachable is the primitive that missing check hands the attacker: a request-controlled stdio spawn config (command / args) arriving at a spawn sink. That is the CVE-2026-42271 shape byte for byte, so this is a second-defence regression fixture against an existing guard, not a new guard. A deployment that routes registration payloads through :class:~agent_airlock.mcp_spec.subprocess_arg_guard.McpSubprocessArgInjectionGuard survives the auth hole; one that does not, does not.