CVE-2026-54769
Langroid: RCE via insecure `eval()` sandbox due to `__builtins__` access.
- CVSS 10.0
- CWE-94
- Design Defects
- Remote
Langroid is a framework for building large-language-model-powered applications. Versions prior to 0.65.2 are vulnerable to a critical Sandbox Escape leading to Remote Code Execution (RCE) in its `TableChatAgent` and `VectorStore` capabilities. When these agents evaluate LLM-generated tool messages with `full_eval=True`, they attempt to sandbox the execution by explicitly setting `locals` to an empty dictionary `{}` inside Python's `eval()` function. However, this relies on an incomplete understanding of Python's execution model. Because `__builtins__` is not explicitly scrubbed from the `globals` dictionary mapping, Python implicitly injects all built-ins during execution, granting full access to functions like `__import__('os').system()`. Since `TableChatAgent.pandas_eval()` executes external LLM outputs natively, this bypass permits any attacker providing prompt payload to achieve unauthenticated RCE on the host system. Version 0.65.2 patches the issue.
- CWE
- CWE-94
- CVSS base score
- 10.0
- Published
- 2026-07-10
- OWASP
- A03 Injection
- Orthogonal defect classification
- Checking
- Code defect classification
- Incorrect Check
- Category
- Design Defects
- Subcategory
- Command Injection
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- Langroid
- Fixed by upgrading
- Yes
Solution
Upgrade to Langroid version 0.65.2 or later.
Vulnerable code sample
import pandas as pd
class VulnerableTableChatAgent:
"""
A simplified representation of Langroid's TableChatAgent prior to version 0.65.2,
demonstrating the vulnerability CVE-2026-54769.
"""
def __init__(self):
# The agent would typically manage a pandas DataFrame.
self.df = pd.DataFrame({'user': ['Alice', 'Bob'], 'visits': [10, 22]})
def pandas_eval(self, code_from_llm: str):
"""
Simulates the vulnerable method that evaluates LLM-generated code.
The attempt to sandbox execution by setting `locals` to an empty
dictionary is incomplete and can be bypassed.
"""
# This is the vulnerable call as described in the CVE.
# `globals` is provided, but `__builtins__` is not scrubbed from it.
# Python's `eval` function will implicitly add `__builtins__` to the
# globals dictionary if it's missing, granting access to all built-in
# functions, including the dangerous `__import__`.
globals_for_eval = {"df": self.df}
locals_for_eval = {} # The failed sandbox attempt.
try:
# An attacker can provide a payload like:
# "__import__('os').system('echo RCE achieved')"
# This code will be executed by the host system.
result = eval(code_from_llm, globals_for_eval, locals_for_eval)
return result
except Exception as e:
return f"Error: {e}"Patched code sample
def safe_pandas_eval(code_string: str, df=None, pd=None):
"""
This function represents the patched code that fixes CVE-2026-54769.
The vulnerability existed because Python's eval() function, when given a `globals`
dictionary that does not contain a `__builtins__` key, will implicitly add
the caller's `__builtins__`. This allows access to dangerous functions like
`__import__`, leading to Remote Code Execution (RCE).
The fix is to explicitly provide a `globals` dictionary to eval() that contains
a `__builtins__` key with a restricted (or empty) dictionary. This prevents
Python from adding the default, unsafe built-ins.
"""
# The globals dictionary is defined with __builtins__ explicitly set to an
# empty dictionary, effectively creating a sandbox.
# Any safe, required modules like 'pd' (pandas) or variables like 'df'
# are added explicitly to this safe dictionary.
safe_globals = {
"__builtins__": {},
"pd": pd,
"df": df,
}
try:
# Calling eval() with the sanitized globals dictionary. An attempt to use
# a dangerous built-in (e.g., `__import__('os').system('ls')`) will now
# raise a NameError because `__import__` is not defined in the scope.
return eval(code_string, safe_globals, {})
except Exception as e:
# The exception demonstrates that the malicious code was blocked.
return f"Execution blocked: {e}"Payload
__import__('os').system('touch /tmp/pwned')
Cite this entry
@misc{vaitp:cve202654769,
title = {{Langroid: RCE via insecure `eval()` sandbox due to `__builtins__` access.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-54769},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-54769/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
