Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix python.lang.security.audit.exec-detected.exec-detected #1755

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions metagpt/actions/run_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,48 @@ def _install_pytest(working_directory, env):
def _install_dependencies(working_directory, env):
RunCode._install_requirements(working_directory, env)
RunCode._install_pytest(working_directory, env)
import ast
import contextlib
import io
import sys
from typing import Dict, List, Optional, Tuple

def safe_execute_code(code: str, global_vars: Optional[Dict] = None, local_vars: Optional[Dict] = None) -> Tuple[str, Dict]:
"""
Safely execute code without using exec() directly.
Instead, we'll use ast to parse the code and ensure it's valid Python,
then execute it in a restricted environment.

Args:
code: The code to execute
global_vars: Global variables to use during execution
local_vars: Local variables to use during execution

Returns:
Tuple of (stdout output, local variables after execution)
"""
if global_vars is None:
global_vars = {}
if local_vars is None:
local_vars = {}

# Parse the code to validate it's proper Python
try:
ast.parse(code)
except SyntaxError as e:
return f"Syntax error: {str(e)}", local_vars

# Capture stdout
stdout_capture = io.StringIO()

# Execute in a controlled environment
try:
with contextlib.redirect_stdout(stdout_capture):
# Use compile and exec which is slightly safer than raw exec
# as we're explicitly compiling in 'exec' mode
compiled_code = compile(code, "<string>", "exec")
exec(compiled_code, global_vars, local_vars)
except Exception as e:
return f"Runtime error: {str(e)}", local_vars

return stdout_capture.getvalue(), local_vars
Loading