CVE-2026-25874: Hugging Face LeRobot Unauthenticated RCE via Pickle Deserialization

Introduction

A critical remote code execution (RCE) vulnerability, CVE-2026-25874, affects Hugging Face's open-source robotics platform, LeRobot. The async inference PolicyServer component is susceptible. The vulnerability comes from insecure deserialization of untrusted data using Python's pickle module over exposed gRPC endpoints.

This Hugging Face LeRobot Unauthenticated RCE via Pickle Deserialization allows an unauthenticated attacker, with network access to the PolicyServer, to send a malicious serialized payload. This can execute arbitrary operating system commands on the host machine running the service. LeRobot's design for GPU-backed inference systems, often operating with elevated privileges and access to critical resources, means the implications of this vulnerability are significant for system security.

PurpleOps has previously detailed vulnerabilities like this, including an analysis of a similar unauthenticated RCE in LeRobot. Understanding these critical flaws is essential for strong security.

What is CVE-2026-25874 and why is it critical?

CVE-2026-25874 is a security vulnerability in Hugging Face LeRobot, specifically its async inference PolicyServer component. The vulnerability allows unauthenticated remote code execution (RCE) through unsafe deserialization of attacker-controlled data. This process uses Python's pickle module over exposed gRPC endpoints.

This vulnerability is critical because of several factors. A remote attacker capable of reaching the vulnerable service can execute arbitrary operating system commands on the PolicyServer host machine. LeRobot's architecture often involves GPU-backed systems that may have elevated privileges and access to sensitive resources, including robotics hardware, internal networks, and proprietary datasets. Such access makes CVE-2026-25874 a high-impact threat, potentially leading to full system compromise and operational disruption. Detecting such vulnerabilities requires advanced breach detection.

LeRobot Overview

LeRobot is Hugging Face's platform for robotics and machine learning. It trains and deploys robot policies using AI models. Its async inference design separates robot control from intensive model inference. A RobotClient operates on the robot device, while the PolicyServer runs on a dedicated GPU machine. The robot transmits observations (e.g., camera frames, sensor data), and the server returns corresponding actions (e.g., movement commands). This architecture improves performance, but it also creates a network-exposed service that must process remote input securely.

LeRobot Workflow

The system uses a distributed robotics architecture where the robot manages sensing and movement, and a remote GPU server handles AI decision-making. This design aims to make robots more cost-effective, intelligent, and scalable.

  1. Robot Side: The robot client (e.g., robot_client.py) operates on the robot, gathering data from sensors such as cameras, LiDAR, and motion sensors. This data forms an observation representing the robot's current state.
  1. Sending Data to the Server: The robot transmits the observation to the remote GPU server via gRPC. Data is packaged into an Observation Message and sent over the network for remote AI inference. This design allows robots to use powerful compute hardware without carrying onboard GPUs.
  1. GPU Server / Policy Server: The Policy Server (e.g., policy_server.py) exposes gRPC methods like SendObservations() and SendPolicyInstructions() to receive data from the robot. Inside the server, observation data undergoes processing, and a trained AI policy model runs on the GPU to determine the next robot action.
  1. Returning Actions: After inference, the server sends an Action Message back to the robot, containing movement commands.
  1. Robot Executes Commands: The robot control system receives the action and activates motors, actuators, wheels, or robotic arm joints to perform the task.

Why LeRobot's Architecture is Important

LeRobot simplifies robotics by offering ML-style workflows familiar to AI developers. This contrasts with traditional robotics, which requires extensive mechanical engineering and control systems expertise. It connects AI models from simulation to real-world applications on robot arms, mobile robots, and physical tasks. As an open-source ecosystem, it provides training pipelines, dataset tools, inference servers, and deployment tools, encouraging collaboration. Hugging Face intends for LeRobot to standardize robotics AI, similar to its impact on NLP models.

Vulnerability Details

The CVE-2026-25874 vulnerability is an unauthenticated remote code execution (RCE) flaw affecting Hugging Face LeRobot, specifically its async inference PolicyServer component. This flaw allows attackers to execute arbitrary commands remotely without authentication.

Which products and versions are affected by CVE-2026-25874?

The vulnerability has been confirmed in LeRobot v0.4.3. It was successfully validated in a test environment using the official PyPI release with the default async inference PolicyServer component enabled. Earlier LeRobot releases that include the lerobot.async_inference.policy_server architecture and deserialize untrusted gRPC input using Python pickle.loads() are also likely affected. Any version where the vulnerable RPC handlers, SendPolicyInstructions() and SendObservations(), remain present is susceptible.

Technical Root Cause of CVE-2026-25874

The vulnerability comes from unsafe deserialization of attacker-controlled network input within LeRobot's async inference PolicyServer. The service accepts raw bytes from remote gRPC clients and directly passes them into Python's deserialization routine: pickle.loads(...).

This is a serious security issue because Python's pickle format is not designed for untrusted data. Unlike passive formats such as JSON or Protobuf, pickle can reconstruct arbitrary Python objects and execute logic during the loading process. An attacker can craft a malicious serialized object that abuses built-in object restoration mechanisms, such as reduce(), reduce_ex(), or setstate(). These methods can invoke functions like os.system(), subprocess.Popen(), or other attacker-controlled operations during deserialization itself. Code execution can occur before any application-level validation, type checks, or exception handling takes place. This type of vulnerability, like the Apache ActiveMQ RCE CVE-2025-54539, shows common deserialization pitfalls.

Vulnerable RPC Handlers

The LeRobot PolicyServer exposes two gRPC RPC handlers that directly deserialize network data using Python pickle.loads(). This is the core security flaw.

  1. SendPolicyInstructions()
    def SendPolicyInstructions(self, request, context):

policy_specs = pickle.loads(request.data) # nosec

if not isinstance(policy_specs, RemotePolicyConfig):

raise TypeError(...)

Upon client connection and sending raw bytes in request.data, the server immediately executes pickle.loads(request.data). The type check (isinstance(policy_specs, RemotePolicyConfig)) occurs only after deserialization. With Python pickle, malicious code can execute during pickle.loads(), making the subsequent type check ineffective. Even if the object is invalid and raises an exception, the attack payload may have already executed.

  1. SendObservations()
    def SendObservations(self, request_iterator, context):

received_bytes = receive_bytes_in_chunks(...)

timed_observation = pickle.loads(received_bytes) # nosec

An attacker can stream bytes to the server. The server reconstructs the full payload and executes pickle.loads(received_bytes). Arbitrary code can execute immediately during this process.

The # nosec comment in the code typically suppresses static security scanner warnings, such as B301: pickle usage is insecure from Bandit. This indicates developer awareness of pickle's risks but an organizational decision to suppress the warning rather than mitigate the vulnerability. Type validation mechanisms like isinstance() are ineffective against pickle-based RCEs because special methods (reduce(), setstate()) can execute commands during object reconstruction, before type checks are performed.

Exploitation and Impact

The CVE-2026-25874 vulnerability allows an unauthenticated attacker to achieve remote code execution on systems running the vulnerable LeRobot PolicyServer. Exploitation involves crafting a malicious pickle payload that, upon deserialization, triggers arbitrary operating system commands. Organizations benefit from a cyber threat intelligence platform that provides real-time ransomware intelligence and monitors underground forum intelligence for early warnings of exploit developments.

Exploit Script Analysis

A Python script shows how to exploit the LeRobot PolicyServer vulnerability by sending a malicious pickle payload to the exposed gRPC service. The script abuses insecure deserialization in the SendPolicyInstructions() and SendObservations() RPC handlers to achieve RCE.

The script uses modules for os (to run system commands), pickle (to create malicious payloads), grpc (for communication), and argparse (for command-line options). The exploit uses a malicious RCE class:

class RCE:

def init(self, cmd):

self.cmd = cmd

def reduce(self):

return (os.system, (self.cmd,))

The reduce() method instructs pickle to call os.system(command) during object reconstruction. When the server deserializes this object, the embedded command executes automatically. The script connects to the exposed PolicyServer via insecure gRPC, builds the malicious pickle bytes, and then sends them to either or both of the vulnerable RPC endpoints (SendPolicyInstructions() or SendObservations()). An RPC error is typically expected after successful exploitation, as the command has already executed.

Real-World Test Environment

The vulnerability was validated against the official LeRobot v0.4.3 package, installed directly from PyPI without source code modifications. Testing used the default async inference PolicyServer component.

To start the vulnerable PolicyServer:

python3 -m lerobot.async_inference.policy_server --host=0.0.0.0 --port=50051

A malicious client was executed against the exposed server:

python3 ex1.py --target 127.0.0.1:50051 --method both --cmd "cat /etc/passwd > /tmp/x"

The exploit successfully triggered unsafe deserialization through the vulnerable RPC handlers, leading to command execution on the target host. The contents of /etc/passwd were written to /tmp/x, confirming arbitrary OS command execution.

How the Attack Works

  1. Craft Malicious Payload: An attacker creates a specially crafted Python pickle object containing a hidden system command, abusing reduce() for automatic execution upon deserialization.
  2. Send Payload via gRPC: The malicious serialized bytes transmit to the vulnerable LeRobot PolicyServer using exposed gRPC endpoints like SendPolicyInstructions() or SendObservations(). Insecure gRPC transport means no authentication or encrypted connection is required.
  3. Unsafe Deserialization: The server processes the attacker-controlled bytes with pickle.loads(). Pickle reconstructs Python objects and executes embedded instructions during loading.
  4. Remote Code Execution: During deserialization, the hidden payload triggers the supplied operating system command automatically, granting the attacker arbitrary command execution with the LeRobot service's privileges.
  5. Result Written on Target: The command's output is written to a local file on the compromised machine (e.g., /etc/passwd redirected to /tmp/x).
  6. Full System Compromise Potential: Once command execution is achieved, an attacker can steal credentials, install malware, establish persistence, or move laterally within the internal network. Dark web monitoring service and telegram threat monitoring can provide early indications of discussions around exploit capabilities and potential targets. This also shows the need for strong supply-chain risk monitoring as open-source components like LeRobot can introduce vulnerabilities.

Impact of the Vulnerability

The impact of CVE-2026-25874 is significant:

  • Unauthenticated Remote Code Execution: An attacker with network access can execute arbitrary commands on affected LeRobot systems without requiring authentication or prior privileges.
  • Full Server Compromise: Successful exploitation can lead to a complete takeover of the PolicyServer host, allowing attackers to access files, install malware, or maintain persistence.
  • Client / Robot Compromise: Connected robot clients may also be affected through the same insecure channel, exposing onboard systems, local storage, and control processes.
  • Theft of Sensitive Data: Attackers may steal API keys, SSH credentials, model files, and internal data. Captured secrets can be reused for deeper network compromise. This shows the need for effective credential intelligence.
  • Internal Network Pivoting: Compromise of the PolicyServer enables lateral movement to other trusted systems, as GPU servers and robotics environments often reside in privileged networks.
  • Service Disruption and Sabotage: Attackers can crash services, corrupt models, or halt robot operations, disrupting research, automation, or production workflows.
  • Physical Safety Risk: If tied to real robots, malicious commands could cause unsafe movement, creating operational and safety concerns. Detecting such incidents swiftly is crucial, often facilitated by live ransomware API feeds for intelligence on active threats and brand leak alerting for compromised credentials.

Mitigation and Patches

Addressing the CVE-2026-25874 vulnerability requires focusing on secure coding practices, network security, and host hardening. While a direct patch from Hugging Face is the ideal solution, several remediation steps can secure systems against this type of deserialization vulnerability.

What are the mitigation steps for CVE-2026-25874?

Standard practices for addressing this vulnerability include:

  • Remove Pickle from Network Input: Replace pickle.loads() with secure deserialization formats. Formats such as JSON, Protobuf, or safetensors are designed to be safe for untrusted data. Pickle should never be used on attacker-controlled data due to its capability to execute arbitrary code.
  • Enable TLS Encryption: Implement add_secure_port() with appropriate certificates instead of add_insecure_port(). TLS encrypts traffic, protecting it from interception, and verifies the server's identity, preventing man-in-the-middle attacks.
  • Add Authentication: Require API tokens, mutual TLS (mTLS), or JSON Web Token (JWT) validation for all gRPC clients. Only trusted robots and internal systems should be authorized to access the PolicyServer.
  • Restrict Network Access: Prevent public exposure of the PolicyServer and only permit access from trusted IP addresses, private networks, or through firewalls and VPNs.
  • Disable Async Components if Unused: Temporarily disable the PolicyServer or remote inference functionality if it is not required. Running local inference is inherently safer until an official patch becomes available.
  • Harden the Host System: Configure the service to run as a non-root user within a restricted container environment. Employ security mechanisms such as AppArmor, SELinux, and least-privilege controls to limit the potential damage from a successful exploit. This is a key aspect of supply-chain risk monitoring, as the compromise of one component can affect the entire system.
  • Monitor for Exploitation: Implement continuous monitoring for suspicious activities, including unusual child processes, reverse shells, unexpected file creation (e.g., in /tmp/), or abnormal outbound network traffic. Alert on instances where Python spawns unusual processes like bash, curl, or nc. This is a key capability of any cyber threat intelligence platform.

Technical Takeaways

  • CVE-2026-25874 is an unauthenticated RCE in Hugging Face LeRobot's PolicyServer.
  • The vulnerability originates from insecure deserialization of untrusted gRPC input using pickle.loads().
  • Python's pickle module is unsuitable for untrusted data, allowing arbitrary code execution during object reconstruction via methods like reduce().
  • The vulnerable RPC handlers are SendPolicyInstructions() and SendObservations(), which execute pickle.loads() before type validation.
  • Successful exploitation can lead to full server compromise, data theft, internal network pivoting, and potential physical safety risks in robotics deployments.
  • Effective mitigation involves replacing pickle with secure formats, implementing strong authentication, encrypting communications, and restricting network access.