Skip to main content

EpicBox runs untrusted code in secure Docker based sandboxes

Project description

epicbox2

A Python library to run untrusted code in secure, isolated Docker based sandboxes.

It allows to spawn a process inside one-time Docker container, send data to stdin, and obtain its exit code and stdout/stderr output. It's very similar to what the subprocess module does but additionally you can specify a custom environment for the process (a Docker image) and limit the CPU, memory, disk, and network usage for the running process.

Usage

Run a simple Python script in a one-time Docker container using the python:3.6.5-alpine image:

import epicbox

epicbox.configure(
    profiles=[
        epicbox.Profile('python', 'python:3.6.5-alpine')
    ]
)
files = [{'name': 'main.py', 'content': b'print(42)'}]
limits = {'cputime': 1, 'memory': 64}
result = epicbox.run('python', 'python3 main.py', files=files, limits=limits)

The result value is:

{'exit_code': 0,
 'stdout': b'42\n',
 'stderr': b'',
 'duration': 0.143358,
 'timeout': False,
 'oom_killed': False}

Alternatively, you can also use the session context manager:

from epicbox import create_session

with create_session("python") as session:
    command = (
        "python3 -c 'import sys; "
        'print("stdout data"); print("stderr data", file=sys.stderr)\''
    )
    result = session.exec(command)
    # result contains stdout and stderr

The advantage of a session is that a container will start upon entering the context manager, and commands can be run via exec. The standard run commands will create and start a new container for every command.

Available Limit Options

The available limit options and default values:

DEFAULT_LIMITS = {
    # CPU time in seconds, None for unlimited
    'cputime': 1,
    # Real time in seconds, None for unlimited
    'realtime': 5,
    # Memory in megabytes, None for unlimited
    'memory': 64,

    # limit the max processes the sandbox can have
    # -1 or None for unlimited(default)
    'processes': -1,
}

Advanced usage

A more advanced usage example of epicbox is to compile a C++ program and then run it multiple times on different input data. In this example epicbox will run containers on a dedicated Docker Swarm cluster instead of locally installed Docker engine:

import epicbox

PROFILES = {
    'gcc_compile': {
        'docker_image': 'stepik/epicbox-gcc:6.3.0',
        'user': 'root',
    },
    'gcc_run': {
        'docker_image': 'stepik/epicbox-gcc:6.3.0',
        # It's safer to run untrusted code as a non-root user (even in a container)
        'user': 'sandbox',
        'read_only': True,
        'network_disabled': False,
    },
}
epicbox.configure(profiles=PROFILES, docker_url='tcp://1.2.3.4:2375')

untrusted_code = b"""
// C++ program
#include <iostream>

int main() {
    int a, b;
    std::cin >> a >> b;
    std::cout << a + b << std::endl;
}
"""
# A working directory allows to preserve files created in a one-time container
# and access them from another one. Internally it is a temporary Docker volume.
with epicbox.working_directory() as workdir:
    epicbox.run('gcc_compile', 'g++ -pipe -O2 -static -o main main.cpp',
                files=[{'name': 'main.cpp', 'content': untrusted_code}],
                workdir=workdir)
    epicbox.run('gcc_run', './main', stdin='2 2',
                limits={'cputime': 1, 'memory': 64},
                workdir=workdir)
    # {'exit_code': 0, 'stdout': b'4\n', 'stderr': b'', 'duration': 0.095318, 'timeout': False, 'oom_killed': False}
    epicbox.run('gcc_run', './main', stdin='14 5',
                limits={'cputime': 1, 'memory': 64},
                workdir=workdir)
    # {'exit_code': 0, 'stdout': b'19\n', 'stderr': b'', 'duration': 0.10285, 'timeout': False, 'oom_killed': False}

Installation

epicbox can be installed by running pip install epicbox2. It's tested on Python 3.4+ and Docker 1.12+.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

epicbox2-2.0.0.tar.gz (22.1 kB view details)

Uploaded Source

Built Distribution

epicbox2-2.0.0-py3-none-any.whl (17.0 kB view details)

Uploaded Python 3

File details

Details for the file epicbox2-2.0.0.tar.gz.

File metadata

  • Download URL: epicbox2-2.0.0.tar.gz
  • Upload date:
  • Size: 22.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for epicbox2-2.0.0.tar.gz
Algorithm Hash digest
SHA256 1417a49b681db4e1ce0021bb4b3f84ad09160ee2f40526a7e31a9485b4058c9c
MD5 b874ad457c8349182d07942554305f3f
BLAKE2b-256 2425b059ec1464f20568bd614014f878ee8295c4b97ec73a0f7cce8b950c3da3

See more details on using hashes here.

File details

Details for the file epicbox2-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: epicbox2-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 17.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.12.3

File hashes

Hashes for epicbox2-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3a5e87f34e5bef830cf5872e7c85273be08802bd361fc4bb04d96d9a28a64ace
MD5 da4cbb7657260570f3c92bb4c2035320
BLAKE2b-256 d23bba988884238052642002d8a1041308ac01d9f4fb5df4ab010b48b69dbcf7

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page