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

Introduction

CVE-2026-25874 is a remote code execution (RCE) vulnerability affecting LeRobot, Hugging Face's open-source robotics platform. The async inference PolicyServer component has this flaw, which allows unauthenticated attackers to execute arbitrary code. This happens due to insecure deserialization of untrusted data via Python's pickle module over exposed gRPC endpoints.

This vulnerability poses a major risk because PolicyServer instances often run in environments with GPU-backed inference systems. These systems typically have elevated privileges and access to robotics hardware, internal networks, proprietary datasets, and expensive compute resources. An attacker exploiting CVE-2026-25874 could take full control of the host machine, leading to widespread compromise.

Organizations using LeRobot must fix this issue quickly to prevent unauthorized access and potential disruption. This analysis details the vulnerability, its exploitation, and recommended solutions.

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

CVE-2026-25874 is a security vulnerability in Hugging Face LeRobot, specifically in its async inference PolicyServer component. This flaw allows unauthenticated remote code execution (RCE) through unsafe deserialization of attacker-controlled data via Python's pickle module across exposed gRPC endpoints. A remote attacker who can reach the service can execute arbitrary operating system commands on the PolicyServer host machine.

This vulnerability is important for several reasons. LeRobot helps train and deploy AI models for robotic policies. Its architecture separates robot control (RobotClient) from heavy model inference (PolicyServer), with the PolicyServer often running on GPU machines. This means the vulnerable component frequently resides in privileged network segments, managing sensitive data and controlling physical hardware. Unauthenticated RCE on such a system can lead to full server compromise, data theft, operational disruption, and physical safety risks if connected to active robots.

Vulnerability Details

LeRobot is Hugging Face's platform for robotics and machine learning. It helps with training and deploying robot policies using AI models. Its async inference architecture distributes tasks: a RobotClient operates on the robot, while a PolicyServer runs on a remote GPU machine. Robot sensor observations go to the PolicyServer, which then performs AI inference and returns actions. This distributed model improves performance but exposes the PolicyServer as a network-accessible service, requiring secure input processing.

CVE-2026-25874 centers on insecure deserialization of untrusted network input in LeRobot's async inference PolicyServer. The service accepts raw bytes from remote gRPC clients and processes them directly using Python's pickle.loads(...) routine. Python's pickle format is unsafe for untrusted data because it can reconstruct arbitrary Python objects and execute embedded logic during loading. Safer, more passive formats include JSON or Protobuf. For more on serialization injection vulnerabilities, see our analysis on LangChain Serialization Injection.

An attacker can create a malicious serialized object that uses built-in object restoration mechanisms, such as reduce(), reduce_ex(), or setstate(). These methods can be abused to invoke system commands like os.system() or subprocess.Popen() during the deserialization process. This means code execution can happen before any application-level validation, type checks, or exception handling mechanisms trigger, making them useless. This bypass of security checks creates a dangerous attack vector.

Affected Versions

The following versions are vulnerable:

  • LeRobot v0.4.3: This version was confirmed vulnerable in a real-world test environment using the official PyPI release with the default async inference PolicyServer component enabled.
  • Earlier LeRobot releases: Any previous versions using the lerobot.async_inference.policy_server architecture that deserialize untrusted gRPC input using pickle.loads() are likely affected. This includes any version where the vulnerable RPC handlers, SendPolicyInstructions() and SendObservations(), are present. Organizations should use supply-chain risk monitoring for all components in their AI and robotics infrastructure.

Vulnerable RPC Handlers

The LeRobot PolicyServer exposes two gRPC RPC handlers that directly deserialize network-received data using Python's 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(...)

In this handler, the server immediately executes pickle.loads(request.data) when it receives client data. A type check, isinstance(policy_specs, RemotePolicyConfig), happens only after deserialization. This timing is key because malicious code in the pickle payload can execute during pickle.loads(), before the type check. Even if the deserialized object is invalid and an exception is raised, the attacker's payload may have already run.

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

received_bytes = receive_bytes_in_chunks(...)

timed_observation = pickle.loads(received_bytes) # nosec

Similarly, the SendObservations() handler rebuilds a full payload from streamed bytes before calling pickle.loads(received_bytes). This shows the same vulnerability, allowing arbitrary code to run as soon as deserialization starts.

The # nosec comment next to pickle.loads() indicates an awareness of the inherent risks of using pickle for untrusted data. This comment typically suppresses warnings from static security scanners like Bandit, which would flag B301: pickle usage is insecure. The warning was suppressed instead of the issue being fixed with safer serialization methods. This shows the importance of breach detection to find and respond to such risks before exploitation.

Type validation, like if not isinstance(obj, SafeType):, does not fix this vulnerability. The pickle.loads() function reconstructs objects first. During this reconstruction, special methods like reduce() or setstate() can execute commands, bypassing any subsequent isinstance() checks. Validation occurs too late to prevent the exploit. For more on AI vulnerabilities, including RCE, see our post on AI Cloud Vulnerabilities.

Exploitation and Impact

CVE-2026-25874 allows an unauthenticated attacker to achieve remote code execution on the LeRobot PolicyServer. This section explains how the vulnerability is exploited and its potential effects.

How the exploit works

Exploiting CVE-2026-25874 involves creating a malicious Python pickle payload and sending it to the exposed gRPC service of the LeRobot PolicyServer. This process uses insecure deserialization in the SendPolicyInstructions() and SendObservations() RPC handlers.

The exploit's core is a Python class designed to override the reduce() method. This method, part of Python's pickling protocol, defines how an object is prepared for serialization. By returning the tuple (os.system, (self.cmd,)) from reduce(), an attacker instructs Python to execute os.system(command) when the serialized object deserializes. This enables embedding and executing arbitrary operating system commands.

An attacker would typically follow these steps with a script:

  1. Establish gRPC Connection: Connect to the target LeRobot PolicyServer over insecure gRPC. The default server configuration usually does not require TLS or authentication.
  2. Server Initialization Check: Call the Ready() RPC method to confirm the server is reachable and initialized before sending the malicious payload.
  3. Payload Generation: Serialize an instance of the malicious RCE class, which contains the desired operating system command, using pickle.dumps().
  4. Delivery via SendPolicyInstructions(): Insert the malicious pickle bytes into the PolicySetup.data field and send them to the SendPolicyInstructions() endpoint. The server's pickle.loads(request.data) call triggers command execution.
  5. Delivery via SendObservations(): Alternatively, stream the malicious bytes through the Observation.data field to the SendObservations() endpoint. This targets the pickle.loads(received_bytes) operation on the server, resulting in command execution.

Real-World Test Environment

Validation of CVE-2026-25874 occurred against the official LeRobot v0.4.3 package, installed directly from PyPI without source code changes. Testing focused on the default async inference PolicyServer component.

To reproduce the vulnerability:

  1. Install LeRobot: pip install lerobot
  2. Start the vulnerable PolicyServer: python3 -m lerobot.async_inference.policy_server --host=0.0.0.0 --port=50051
  3. Execute the custom exploit script: python3 ex1.py --target 127.0.0.1:50051 --method both --cmd "cat /etc/passwd > /tmp/x"

The exploit successfully triggered unsafe deserialization via both SendPolicyInstructions() and SendObservations() RPC handlers. This executed the command cat /etc/passwd > /tmp/x on the target host, confirming arbitrary OS command execution by writing /etc/passwd contents to /tmp/x. This shows a major risk, as similar unauthenticated RCE vulnerabilities have appeared in other workflow automation platforms, such as the bug in n8n; read more about it in our post on n8n RCE Critical Bug.

Impact of the Vulnerability

Successful exploitation of CVE-2026-25874 has serious effects on an organization's security.

  • Unauthenticated Remote Code Execution: An attacker with network access can execute arbitrary commands on any affected LeRobot system without authentication, user interaction, or prior privileges. This direct access is a critical failure point.
  • Full Server Compromise: Exploitation means the PolicyServer host can be completely taken over. Attackers can access, modify, or delete files, install persistent malware, or establish backdoors.
  • Client / Robot Compromise: Connected robot clients may also be compromised via the same insecure channel. This can expose onboard systems, local storage, and control processes on the physical robots.
  • Theft of Sensitive Data: Attackers can steal API keys, SSH credentials, proprietary model files, and other internal data. These stolen secrets can then be used for deeper network compromise, making dark web monitoring service and underground forum intelligence important for detecting such leaks.
  • Internal Network Pivoting: Once initial access is gained, the compromised PolicyServer can act as a pivot point. Attackers can move laterally within the internal network to other trusted systems, as GPU servers and robotics environments are often in highly privileged network segments.
  • Service Disruption and Sabotage: Attackers can crash services, corrupt AI models, or halt robot operations. This can lead to significant interruptions in research, automated processes, or production workflows, potentially requiring real-time ransomware intelligence if disruption couples with extortion.
  • Physical Safety Risk: If LeRobot controls physical robots, malicious commands could result in unsafe or unpredictable movements. This brings operational disruption and serious physical safety concerns for personnel and equipment.
  • Brand and Reputation Damage: A major breach detection event, especially one involving physical systems or sensitive AI models, can severely damage reputation. Proactive brand leak alerting helps identify public disclosures of such incidents.

Mitigation and Patches

Addressing CVE-2026-25874 requires immediate and complete action to secure LeRobot deployments. The following steps help reduce the risk of unauthenticated remote code execution.

  1. Replace Pickle from Network Input: The most important step is to stop using pickle.loads() for data received from untrusted network sources. Replace it with safe serialization formats such as JSON, Protobuf, or safetensors. The pickle module should never be used on attacker-controlled data because of its inherent code execution capabilities.
  2. Enable TLS Encryption: Replace add_insecure_port() with add_secure_port() in the gRPC server configuration, using appropriate certificates. TLS (Transport Layer Security) encrypts communication channels, protecting data from interception, verifying server identity, and preventing man-in-the-middle attacks.
  3. Add Authentication: Implement strong authentication for all gRPC clients connecting to the PolicyServer. This could involve API tokens, mutual TLS (mTLS), or JSON Web Token (JWT) validation. Only trusted robots and authorized internal systems should access the PolicyServer. This is a basic step in any secure deployment, supporting a cyber threat intelligence platform strategy.
  4. Restrict Network Access: Implement network segmentation and firewall rules to strictly limit access to the PolicyServer. Block public exposure entirely and allow connections only from known, trusted IP addresses or within private, segmented networks. Use VPNs or other secure networking infrastructure to isolate the service.
  5. Disable Async Components if Unused: If the async PolicyServer or remote inference capabilities are not needed, temporarily disable these components. Running inference locally on the robot or a secure, isolated edge device offers better safety until an official patch or secure configuration is implemented.
  6. Harden the Host System: Apply host-level security practices. Run the LeRobot service as a non-root user with minimal privileges, ideally in a restricted containerized environment. Use security enhancements such as AppArmor or SELinux, and follow the principle of least privilege to limit potential damage from a compromise. Monitoring for suspicious activities, such as unusual child processes or outbound connections, is also important. Consider telegram threat monitoring for threat actor discussions or a live ransomware API for immediate threat indicators.
  7. Monitor for Exploitation: Implement continuous monitoring for indicators of compromise (IoCs) on systems running LeRobot PolicyServer. Look for suspicious child processes spawned by the Python application, attempts to create reverse shells, or unexpected file creations in temporary directories (e.g., /tmp/). Alert on Python processes spawning shell commands (bash, sh), network utilities (curl, nc), or unusual outbound network traffic patterns. Effective breach detection is key here.

Technical Takeaways

  • CVE-2026-25874 is an unauthenticated RCE vulnerability in Hugging Face LeRobot's PolicyServer.
  • The vulnerability comes from insecure pickle.loads() deserialization on untrusted gRPC input.
  • Exploitation uses Python's reduce() method to execute arbitrary OS commands during deserialization.
  • Affected components include SendPolicyInstructions() and SendObservations() RPC handlers in LeRobot v0.4.3 and likely earlier versions.
  • The flaw can cause full server compromise, data theft, service disruption, and physical safety risks in robotic deployments.
  • To fix this, replace pickle with safe serialization formats, enable TLS and authentication, restrict network access, and apply strong host hardening and monitoring.