Agno and LMDeploy expose two critical AI runtime boundaries
CVE-2026-76832 escapes Agno's base_dir while CVE-2026-76850 abuses pickle in LMDeploy. We examine fixes, exposure and runtime isolation.
- AUTHOR
- Karol Rapacz / CEO Breachroad · OSCP · PNPT
- PUBLISHED
- 19 August 2026
- READING TIME
- 17 min read
- TOPIC
- AI Security
Two security records in focus on 19 August 2026 show different ways to cross an AI runtime boundary. CVE-2026-76832 is a path traversal in Agno’s PythonTools: a filename could escape the configured base_dir, enabling file read, write or execution. CVE-2026-76850 affects LMDeploy: the peer connector for disaggregated serving received ZeroMQ objects with recv_pyobj(), which invokes pickle.loads() on data from a remote peer.
The projects, prerequisites and timelines are separate. Agno introduced protection in release 2.3.24 on 8 January; the CVE record became public on 19 August. LMDeploy 0.16.0 shipped on 19 August and replaced pickle with JSON; its CVE record gives 29 July as the public date and identifies versions 0.9.2 through releases before 0.16.0 as affected. The shared lesson is not one campaign, but excessive trust in directory and cluster-transport boundaries.
CVE-2026-76832: Agno PythonTools escapes base_dir
PythonTools gives an agent actions such as reading a file, saving a file and running a Python file. The vulnerable implementation constructed a path by joining base_dir with a controlled file_name. joinpath() alone does not guarantee that the result remains under the base directory.
If file_name contains parent-directory traversal, an absolute path or a suitably prepared link, the result can name a file outside the expected workspace. An attacker does not need to invoke the tool manually. An instruction may exist inside an issue, repository, RAG document or web page the agent analyses. The model submits a schema-valid argument that violates filesystem policy.
Impact follows the Agno process’s authority. Read access can expose environment files, keys, cloud configuration and code from other projects. Write access may modify a script run later, startup file, application configuration or CI artefact. run_python_file raises impact to code execution when an agent selects a file beyond the trusted directory.
The CNA record scores the CVE 8.8 under CVSS 3.1 and 8.5 under CVSS 4.0. Its scenario includes user interaction or processed content leading to tool invocation. Not every Agno application automatically exposes PythonTools; the deployed agent configuration decides exposure.
How the Agno fix works
The patch introduces restrict_to_base_dir and path checking. A correct pattern canonicalises the path and verifies that it remains relative to the resolved base directory. Agno 2.3.24 describes automatic blocking of operations outside contextual base_dir for PythonTools and MLXTranscribeTools.
The flag can be deliberately disabled to allow outside operations. Library version alone may therefore be insufficient proof of mitigation. Check restrict_to_base_dir, custom subclasses and wrappers that may bypass the new helper.
Even correct resolution is not an operating-system sandbox. The process may still read everything it can access through another tool or library. Races between check and use, mounts and special files also exist. The stronger defence is a separate container or microVM with an ephemeral filesystem, read-only root, minimal workspace and no host secrets.
CVE-2026-76850: pickle in the LMDeploy peer connector
LMDeploy serves and deploys models. In disaggregated serving, engines communicate to split stages and transfer state. The vulnerable handle_zmq_recv received a message through ZeroMQ recv_pyobj(). That function deserialises a Python object with pickle before the code checks whether the result is a DistServeCacheFreeRequest.
Post-deserialisation type checking is not a boundary. Pickle can identify a function to invoke while reconstructing an object. A malicious payload acts before isinstance. This is the classic CWE-502 pattern: Deserialization of Untrusted Data.
The CVE record also explains the route to an attacker-controlled peer. /distserve/p2p_initialize and /distserve/p2p_connect accept remote-engine information including its ZeroMQ address. API authentication is absent when the server uses the default api_keys=None. An attacker who can reach the API may point an engine at a controlled ZMQ endpoint and supply an object for deserialisation.
CVSS 3.1 is 9.8 and CVSS 4.0 is 9.3. Disaggregated serving must be enabled; the receive loop does not start for an ordinary deployment without that feature. External API reachability and missing keys determine practical exposure.
LMDeploy 0.16.0 moves to JSON
The fix replaces pickle with JSON for P2P ZeroMQ requests. JSON represents data rather than arbitrary Python object and function graphs. It removes the code-execution capability built into pickle reconstruction. Schema validation, limits, protocol versioning and unknown-field handling remain necessary.
Updating to 0.16.0 or a later supported release is the baseline for the 0.9.2–<0.16.0 range in the CVE. In a multi-node cluster, plan protocol compatibility: a partial rollout may leave an old peer expecting pickle while a new peer emits JSON. Release documentation and a canary test should establish whether rolling upgrade is supported.
JSON does not authenticate the peer. Enable API keys, isolate control-plane endpoints, use mTLS or an authenticated service mesh and restrict ZeroMQ to cluster identities and addresses. An endpoint that initiates a connection should not accept an arbitrary destination from the user network.
A “trusted cluster network” is untrusted input
AI systems often treat worker-to-worker traffic as internal and safe. A shared Kubernetes cluster, developer notebook, compromised worker or exposed API can become a message source. If a protocol uses object deserialisation without cryptographic peer identity, the cluster boundary is merely an assumption.
Segmentation should separate public inference, the control plane and P2P transport. NetworkPolicy or a firewall must restrict both inbound and outbound engine connections. Egress matters because the vulnerable node connects to an address supplied through the request. Allowed hosts should come from service discovery, not a user-controlled body.
Workload identity can bind an engine to a namespace, service account and certificate. Short-lived credentials and mutual TLS make peer impersonation harder. Logs should record initiator, selected endpoint, policy result and protocol version without storing tensors or prompt content.
Agno exposure plan
Find every application using PythonTools or MLXTranscribeTools, including private prototypes and notebooks. Confirm the release from the running environment rather than only a repository lockfile. Determine whether restrict_to_base_dir is active and which directory is used.
After updating to 2.3.24 or later:
- regression-test parent segments, absolute paths, symlinks and separator variants;
- mount one task workspace and use a read-only root filesystem;
- remove Docker sockets, service-account tokens, cloud credentials and host home directories;
- alert on
_check_pathdenials and attempts outside the workspace; - review historical
read_file,save_to_fileandrun_python_filecalls for unusual paths; - rotate a secret where evidence shows it may have been read or important logging gaps prevent exclusion.
Do not test by reading real secrets. Use marker files in an isolated space and confirm policy rejection.
LMDeploy exposure plan
Locate versions 0.9.2–<0.16.0, the API publication path and disaggregated-serving state. Determine whether api_keys was None, who could reach /distserve/*, and whether engines could connect to arbitrary destinations. Update the full cluster to 0.16.0 with compatibility testing.
Hunt for P2P initialisation requests naming addresses outside the cluster, unexpected ZeroMQ connections, engine restarts, child processes and filesystem changes. Preserve container images, API audit records and network flows before cleanup. Where RCE is plausible, rotate workload-reachable tokens and rebuild the node from a trusted image.
Facts and Breachroad conclusions
The path-traversal mechanism, tool methods, CVSS and Agno commit come from the CVE record and repository. The LMDeploy range, recv_pyobj(), endpoints, default api_keys=None, disaggregated-serving prerequisite and JSON fix come from its CVE and 0.16.0 release. MicroVM isolation, mTLS, hunting and rotation are Breachroad guidance.
We do not claim both CVEs belong to one campaign or that every agent and LMDeploy server is reachable. The common conclusion is that a directory guard is not a sandbox and internal transport is not an authenticated protocol.
AI and cybersecurity training helps teams recognise these boundaries in code and architecture. An AI security assessment can verify agent tools, filesystems, serving APIs, P2P protocols, networks and workload identities.


