You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python API/包装器设计模式:用户代码服务器执行实现咨询

Building an API to Execute User-Submitted Code Safely

Hey there! Let's walk through how to design this API properly—because running untrusted user code on your servers is a high-stakes task, so safety and structure are non-negotiable. Here's a breakdown of the key patterns, code handling steps, and critical safeguards you need:

Core Design Patterns to Use

1. Sandbox Pattern (Non-Negotiable)

This is the foundation of your API. The idea is to isolate user code from your main server environment entirely—so even if the code is malicious, it can't access sensitive data, crash your services, or spread to other parts of your infrastructure. You'll implement this with either lightweight sandbox tools or containerization to create a restricted, ephemeral environment for each code execution request.

2. Strategy Pattern

If you plan to support multiple programming languages (Python, JavaScript, etc.), the Strategy Pattern lets you define separate execution "strategies" for each language. For example, you'd have a PythonExecutor, JavaScriptExecutor, and JavaExecutor class—all implementing a common CodeExecutor interface. This keeps your codebase clean and makes it easy to add new languages later.

3. Command Pattern

Wrap each user code request into a CodeExecutionCommand object that includes the code string, target language, user context, and any execution constraints (like time limits). This object can be passed to your executor service, queued if needed, and tracked throughout the execution lifecycle—making it easier to handle retries, logging, and cleanup.

Step-by-Step User Code Handling & Execution

1. Input Validation & Preprocessing

First, clean and validate the user's input:

  • Reject code that contains obvious red flags (like system calls, file access, or network requests) with a static scanner.
  • For typed languages, run a syntax check upfront to catch errors before execution.
  • If your API supports user context (like pre-defined variables or functions), wrap the user's code to inject this context safely. For example, in Python, you might wrap their code in a function that accepts the context as parameters.

2. Sandbox Environment Setup

Choose a sandbox approach based on your security needs:

  • Lightweight Sandboxes: For single-language support, use language-specific restricted modes. For Python, libraries like RestrictedPython let you limit access to built-in functions and modules. Example snippet:
    from RestrictedPython import compile_restricted, safe_globals
    from RestrictedPython.Eval import default_guarded_getitem
    
    def execute_python_code(code, context):
        # Define allowed globals + user context
        restricted_globals = {
            **safe_globals,
            '__getitem__': default_guarded_getitem,
            **context
        }
        try:
            compiled = compile_restricted(code, '<user_code>', 'exec')
            local_vars = {}
            exec(compiled, restricted_globals, local_vars)
            return local_vars.get('output')  # Expect user to store result in 'output'
        except Exception as e:
            return f"Execution Error: {str(e)}"
    
  • Containerization: For stronger isolation (especially multi-language support), use Docker or Kubernetes. Spin up a temporary container with a minimal base image (e.g., python:alpine), mount a read-only filesystem, limit CPU/memory resources, and disable network access. Once execution finishes, destroy the container immediately.

3. Execution & Resource Limiting

  • Timeouts: Set strict time limits (e.g., 5 seconds per request) to prevent infinite loops. For containers, use Docker's --time flag; for process-based sandboxes, use OS-level signals (like SIGALRM in Python).
  • Resource Quotas: Restrict CPU usage (e.g., 0.5 cores) and memory (e.g., 256MB) to prevent user code from hogging server resources.
  • Permission Blocking: Disable access to the host's file system, network, and system calls. For containers, use --network none and mount only empty temporary directories.

4. Result Collection & Cleanup

  • Capture both the code's output (stdout/stderr) and any return values.
  • Immediately destroy the sandbox environment (kill the process, delete the container) to avoid resource leaks.
  • Log all execution details (code, language, duration, errors) for auditing and debugging.

Critical Best Practices

  • Never run user code in your main API process: Use a separate worker pool or container orchestration to handle execution—so a crash or malicious code won't take down your API.
  • Layer your security: Combine static code scanning, sandbox isolation, and resource limits—no single safeguard is enough.
  • Test with malicious code: Simulate attacks (like file deletion, network scans, or resource exhaustion) to make sure your defenses hold.
  • Rate limit requests: Prevent abuse by limiting how many code execution requests a single user can send in a given time window.

内容的提问来源于stack exchange,提问作者Tim Park

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:04:00