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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1417a49b681db4e1ce0021bb4b3f84ad09160ee2f40526a7e31a9485b4058c9c |
|
MD5 | b874ad457c8349182d07942554305f3f |
|
BLAKE2b-256 | 2425b059ec1464f20568bd614014f878ee8295c4b97ec73a0f7cce8b950c3da3 |
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3a5e87f34e5bef830cf5872e7c85273be08802bd361fc4bb04d96d9a28a64ace |
|
MD5 | da4cbb7657260570f3c92bb4c2035320 |
|
BLAKE2b-256 | d23bba988884238052642002d8a1041308ac01d9f4fb5df4ab010b48b69dbcf7 |