Seatbelt Sandboxer

Seatbelt Sandboxer secure sandbox automation and seamless integration

Seatbelt Sandboxer is a community skill for creating sandboxed execution environments, covering process isolation, filesystem restrictions, network policies, resource limits, and security boundaries for safe code execution.

What Is This?

Overview

Seatbelt Sandboxer provides tools for running untrusted code in restricted environments that prevent unauthorized system access. It covers process isolation that confines code execution to separate processes with limited system call access, filesystem restrictions that control which paths the sandboxed process can read and write, network policies that allow or deny network connections based on destination and protocol rules, resource limits that cap CPU time, memory usage, and disk space available to sandboxed processes, and security boundaries that prevent privilege escalation and unauthorized access to system resources. The skill helps developers run code safely.

Who Should Use This

This skill serves platform engineers building code execution services, security teams implementing defense-in-depth for application sandboxing, and developers running user-submitted code in controlled environments.

Why Use It?

Problems It Solves

Running untrusted code without isolation risks arbitrary file access, network exfiltration, and system compromise. Configuring operating system sandboxing primitives requires deep knowledge of seccomp, namespaces, and cgroups. Resource-hungry processes can consume all available CPU and memory without enforcement limits. Testing security boundaries requires understanding attack vectors that sandboxing is designed to prevent.

Core Highlights

Process isolator confines execution with restricted system calls. Filesystem guard controls read and write access to specific paths. Network policy enforces connection rules by destination and protocol. Resource limiter caps CPU, memory, and disk for sandboxed processes.

How to Use It?

Basic Usage

import subprocess
import resource
import tempfile
import os

class Sandbox:
  def __init__(
    self,
    max_mem_mb: int = 256,
    max_cpu_sec: int = 10,
    allowed_dirs:
      list = None
  ):
    self.max_mem = (
      max_mem_mb *
      1024 * 1024)
    self.max_cpu = (
      max_cpu_sec)
    self.allowed = (
      allowed_dirs or [])

  def set_limits(self):
    resource.setrlimit(
      resource.RLIMIT_AS,
      (self.max_mem,
       self.max_mem))
    resource.setrlimit(
      resource.RLIMIT_CPU,
      (self.max_cpu,
       self.max_cpu))

  def run(
    self, code: str
  ) -> dict:
    with tempfile\
      .NamedTemporaryFile(
        suffix='.py',
        mode='w',
        delete=False
    ) as f:
      f.write(code)
      path = f.name

    try:
      result = subprocess\
        .run(
          ['python3', path],
          capture_output=True,
          text=True,
          timeout=
            self.max_cpu,
          preexec_fn=
            self.set_limits)
      return {
        'stdout':
          result.stdout,
        'stderr':
          result.stderr,
        'code':
          result.returncode}
    finally:
      os.unlink(path)

sb = Sandbox(
  max_mem_mb=128,
  max_cpu_sec=5)
out = sb.run(
  'print("hello")')
print(out['stdout'])

Real-World Examples

import subprocess
import json

class DockerSandbox:
  def __init__(
    self,
    image: str =
      'python:3.11-slim',
    memory: str = '256m',
    cpus: str = '0.5',
    network: bool = False
  ):
    self.image = image
    self.memory = memory
    self.cpus = cpus
    self.network = network

  def execute(
    self,
    code: str,
    timeout: int = 30
  ) -> dict:
    cmd = [
      'docker', 'run',
      '--rm',
      f'--memory='
        f'{self.memory}',
      f'--cpus='
        f'{self.cpus}',
      '--read-only']
    if not self.network:
      cmd.append(
        '--network=none')
    cmd.extend([
      self.image,
      'python3', '-c',
      code])

    result = subprocess.run(
      cmd,
      capture_output=True,
      text=True,
      timeout=timeout)
    return {
      'output':
        result.stdout,
      'error':
        result.stderr,
      'exit_code':
        result.returncode}

sandbox = DockerSandbox(
  memory='128m',
  cpus='0.25',
  network=False)
result = sandbox.execute(
  'print(2 + 2)')
print(result['output'])

Advanced Tips

Use read-only filesystem mounts combined with a writable tmpfs for temporary files to prevent persistent modifications. Layer multiple isolation mechanisms including resource limits, network restrictions, and filesystem controls for defense in depth. Monitor sandbox escape attempts by logging blocked system calls.

When to Use It?

Use Cases

Run user-submitted code in a resource-limited sandbox for an online judge platform. Execute untrusted scripts with network isolation to prevent data exfiltration. Create ephemeral Docker containers for safe code evaluation with automatic cleanup.

Related Topics

Sandboxing, process isolation, Docker, security, resource limits, code execution, and container security.

Important Notes

Requirements

Operating system support for resource limits via the resource module or cgroups. Docker or container runtime for container-based sandboxing approaches. Understanding of security boundaries and potential escape vectors for the chosen isolation method.

Usage Recommendations

Do: apply multiple layers of isolation including process, filesystem, and network restrictions. Set strict resource limits to prevent denial of service from resource-intensive code. Use ephemeral containers that are destroyed after each execution.

Don't: rely on a single isolation mechanism since defense in depth provides stronger security guarantees. Run sandboxed code as root since privilege escalation vulnerabilities could bypass other restrictions. Expose host filesystem paths to sandboxed processes without explicit allow-listing.

Limitations

No sandbox is perfectly secure and determined attackers may find escape vectors in any isolation implementation. Resource limiting granularity depends on operating system capabilities and container runtime features. Container-based sandboxing adds startup latency that may not suit real-time execution requirements.