{"id":"GHSA-2vh9-42vm-xmv2","summary":"LMDeploy has Remote Code Execution by Pickle Deserialization via handle_zmq_recv in lmdeploy/lmdeploy/pytorch/disagg/conn/engine_conn.py","details":"## Summary\n\nLMDeploy's PyTorch DistServe/PD-disaggregation control plane used\n`recv_pyobj()` to deserialize messages received through a ZeroMQ PULL\nsocket. PyZMQ implements `recv_pyobj()` using Python pickle\ndeserialization, which can execute arbitrary code while reconstructing\nan object.\n\nThe peer address used by the receiver was supplied through the\n`POST /distserve/p2p_connect` HTTP endpoint. An attacker who could reach\nan affected DistServe API server could cause the server to connect to an\nattacker-controlled ZeroMQ endpoint and deserialize a crafted pickle\npayload.\n\nAPI-key authentication is not enabled unless the operator explicitly\nconfigures it. As a result, affected DistServe deployments without API\nkeys allowed unauthenticated remote code execution with the privileges\nof the LMDeploy serving process.\n\nThis issue affects the PyTorch backend when PD-disaggregation/DistServe\nis enabled. Ordinary deployments that do not use the affected\ndisaggregated-serving path do not expose this data flow.\n\n## Affected components\n\n- HTTP entry point:\n  `lmdeploy/serve/openai/endpoints/distserve.py`,\n  `POST /distserve/p2p_connect`\n- Attacker-controlled peer address:\n  `DistServeConnectionRequest.remote_engine_endpoint_info.zmq_address`\n- Vulnerable receiver:\n  `lmdeploy/pytorch/disagg/conn/engine_conn.py`,\n  `EngineP2PConnection.handle_zmq_recv()`\n- Unsafe operation: `recv_pyobj()`, which performs pickle deserialization\n\n## Vulnerable data flow\n\n1. A caller submits a DistServe P2P connection request containing a\n   ZeroMQ address.\n2. The LMDeploy engine connects its ZeroMQ PULL socket to that address.\n3. `handle_zmq_recv()` receives messages using `recv_pyobj()`.\n4. A malicious peer sends a crafted pickle object.\n5. Python code executes during deserialization, before LMDeploy can\n   perform any type or field validation.\n\n  A type check performed after `recv_pyobj()` cannot mitigate this issue\n  because pickle payload execution occurs during deserialization.\n\n## Impact\n\nSuccessful exploitation allows arbitrary code execution as the\nLMDeploy serving process. This can expose model weights, prompts,\ncredentials, attached storage, cluster-network services, and host or\nGPU resources. An attacker may also modify or terminate the serving\nprocess.\n\n## Affected versions\n\nAffected versions:\n\n- `lmdeploy \u003e= 0.9.2, \u003c 0.16.0`\n\nThe vulnerable P2P receiver was introduced in commit `b0b705f7`.\n\n## Remediation\n\nThe issue was fixed by replacing the pickle-based ZeroMQ protocol with\nJSON serialization:\n\n- `send_pyobj()` was replaced with `send_json()`.\n- `recv_pyobj()` was replaced with `recv_json()`.\n- Received objects are validated using the\n  `DistServeCacheFreeRequest` Pydantic schema before use.\n- Invalid or off-schema messages are rejected without terminating the\n  receive loop.\n\nFix commit:\n\nhttps://github.com/InternLM/lmdeploy/commit/f05b4ad8bf2e2d84101a1d63b3c44fadd99223b2\n\nThe fix was released in LMDeploy 0.16.0.\n\n## Workarounds\n\nUsers who cannot upgrade immediately should:\n\n- Prevent untrusted clients from reaching `/distserve/*` endpoints.\n- Restrict the DistServe HTTP and ZeroMQ control planes to trusted\n  cluster networks.\n- Configure API-key authentication.\n- Block arbitrary outbound ZeroMQ connections from serving nodes.\n\nThese measures reduce exposure but do not make pickle deserialization\nsafe. Upgrading to LMDeploy 0.16.0 or later is recommended.","aliases":["CVE-2025-66455"],"modified":"2026-09-18T17:15:07.086104372Z","published":"2026-09-18T17:03:56Z","database_specific":{"github_reviewed_at":"2026-09-18T17:03:56Z","nvd_published_at":null,"cwe_ids":["CWE-502"],"severity":"CRITICAL","github_reviewed":true},"references":[{"type":"WEB","url":"https://github.com/InternLM/lmdeploy/security/advisories/GHSA-2vh9-42vm-xmv2"},{"type":"WEB","url":"https://github.com/InternLM/lmdeploy/commit/f05b4ad8bf2e2d84101a1d63b3c44fadd99223b2"},{"type":"PACKAGE","url":"https://github.com/InternLM/lmdeploy"},{"type":"WEB","url":"https://github.com/InternLM/lmdeploy/releases/tag/v0.16.0"}],"affected":[{"package":{"name":"lmdeploy","ecosystem":"PyPI","purl":"pkg:pypi/lmdeploy"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.9.2"},{"fixed":"0.16.0"}]}],"versions":["0.10.0","0.10.1","0.10.2","0.11.0","0.11.1","0.12.0","0.12.1","0.12.2","0.12.3","0.13.0","0.14.0","0.15.0","0.9.2","0.9.2.post1"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-2vh9-42vm-xmv2/GHSA-2vh9-42vm-xmv2.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}]}