RestrictedPython
RestrictedPython is a tool that defines a subset of the Python language, allowing program input to be executed within a trusted environment. It is not a full sandbox system but aids in establishing a controlled execution space for untrusted code. The current stable version is 8.1, released on 2025-10-19, and the project maintains an active release cadence.
Warnings
- gotcha RestrictedPython is not a full security sandbox or a secured environment on its own. It provides mechanisms to define a subset of Python and helps in creating a trusted environment, but achieving true security requires careful policy implementation by the user.
- gotcha RestrictedPython officially supports only CPython. It does NOT support PyPy or other alternative Python implementations, as it cannot guarantee its restrictions in those environments.
- breaking Support for `try/except*` clauses was disallowed in version 8.0 due to a possible sandbox escape vulnerability (CVE-2025-22153).
- breaking The `compile_restricted` functions (e.g., `compile_restricted_exec`, `compile_restricted_eval`, `compile_restricted_single`, `compile_restricted_function`) now return a `CompileResult` namedtuple instead of a simple tuple.
- breaking The `Ellipsis` (`...`) statement was re-disallowed in version 5.0 due to unclear security implications, after being allowed in version 4.0.
- breaking Support for older Python versions is progressively dropped with new major/minor releases. For example, Python 3.8 support was dropped in v8.0, and Python 3.7 support was dropped in v7.4.
Install
-
pip install RestrictedPython
Imports
- compile_restricted
from RestrictedPython import compile_restricted
- safe_globals
from RestrictedPython import safe_globals
- safe_builtins
from RestrictedPython import safe_builtins
Quickstart
from RestrictedPython import compile_restricted
from RestrictedPython import safe_globals
source_code = """
def greet(name):
return 'Hello, ' + str(name) + '!'
"""
# Prepare the global namespace for execution
# safe_globals includes __builtins__ with restricted functions/modules
restricted_globals = safe_globals.copy()
# Add any specific names or functions you want to allow in the restricted scope
restricted_globals['_getattr_'] = getattr # Example: allowing getattr in a restricted manner
loc = {}
try:
# Compile the restricted code
byte_code = compile_restricted(
source_code,
filename='<restricted_code>',
mode='exec'
)
# Execute the compiled code within the restricted globals
exec(byte_code, restricted_globals, loc)
# Call the function from the restricted execution's local scope
result = loc['greet']('World')
print(result)
# Example of forbidden operation (will raise error if policy is strict)
# forbidden_code = "import os; os.listdir('/')"
# forbidden_byte_code = compile_restricted(forbidden_code, '<forbidden>', 'exec')
# exec(forbidden_byte_code, safe_globals, {})
except Exception as e:
print(f"An error occurred: {e}")