A sandbox/supervisor for python modules.
Project description
Table of Contents generated with DocToc
secimport
The Tailor-Made Sandbox for Your Application
secimport is production-oriented sandbox toolkit.
It traces your code, and runs an executable that allows only the same syscalls, per module.
Technical Blogs (Free Reading):
The problem
Traditional tools like seccomp or AppArmor enforce syscalls for the entire process.
Something like allowed_syscalls=["read","openat","bind","write"]
, which is great, but not enough for python's attack surface.
The solution
secimport
is able to trace which syscalls each module in your code uses (by package name).
After tracing, secimport creates a JSON/YAML policy for your code. It compiles it into a high-performance eBPF instrumentation script (smaller then 512 bytes overall), that looks like this.
modules:
requests:
destructive: true # when true, secimport will kill on vilation instead of logging.
syscall_allowlist:
- fchmod
- getentropy
- getpgrp
- getrlimit
...
You can also use JSON instaead of YAML, and even confine builtin python modules.
An example policy that uses logging, multiprocessing, os and filesystem will look approximately like this:
...
"/workspace/Python-3.10.0/Lib/logging/__init__.py": [
" clock_gettime",
" getpid",
" write"
],
"/workspace/Python-3.10.0/Lib/multiprocessing/process.py": [
" getcwd",
" getpid",
" getrandom"
],
"/workspace/Python-3.10.0/Lib/multiprocessing/util.py": [
" prlimit64"
],
"/workspace/Python-3.10.0/Lib/os.py": [
" read"
],
"/workspace/Python-3.10.0/Lib/platform.py": [
" uname"
],
"/workspace/Python-3.10.0/Lib/posixpath.py": [
" close",
" fstat",
" getcwd",
" getdents64",
" openat"
],
"/workspace/Python-3.10.0/Lib/random.py": [
" getrandom"
],
...
It was created by tracing the code. secimport automatically finds these per-module syscalls for you.
Finally, you convert this policy into an sandbox (eBPF instrumentation script) to run the python process in production. Running the sandbox will enfore python to obey any given policy.
secimport
is great for...
- Preventing Code Execution: reduce the risk of supply chain attacks.
- Trace the syscalls flow of your application at the user-space/os/kernel level and per module.
- Run your application while enforcing syscalls per module.
- Upon violation of the policy, it can log, stop, or kill the process.
- Protect yourself from RCE:
- secimport makes 1day attacks less of an issue, because it prevents the code form running. If you are using a vulnerable package and someone exploited it, your policy will not allow this exploit's syscalls and it will be handled as you wish.
- Avoid incidents like log4shell. A logging library requires very few syscalls, and it should never run command using fork, execve or spawn.
- The syscalls that "fastapi", "numpy" or "requests" use are very different.
- Load AI Models from Insecure Sources
- Models from unsafe source (huggingface, torch hub, and pytorch pickled models) can be limited to run only a set of syscalls. RCE like 'import os;os.system(...)' somewhere deep in the code will be catched by secimport.
- Minimal Performance Impact
- Has negligible performance impact and is production-ready thanks to eBPF. Check out the Performance benchmarks.
- Trace which syscalls are called by each module in your code.
- secimport uses USDT (Userland Statically Defined Tracing) together with kernel probes in the runtime using eBPF or dtrace instrumentation scripts.
Installation
Tested on Ubuntu, Debian, Rocky (Linux x86/AMD/ARM) and MacOS in (x86/M1). If you run on MacOS you will need to disable SIP for dtrace.
With Docker
For quicker evaluation, we recommend using the Secimport Docker Image instead of self-installing.
- Build and run the Docker container with a custom kernel that matches your existing OS kernel version:
A temporary container will be created, and you will be logged in as the root user.cd docker/ && ./build.sh && ./run.sh
Without Docker
- Install python with USDT probes by configuring it with '--dtrace'
- Install one of the backends: eBPF or DTrace.
- Install secimport
- Install from pypi
-
python3 -m pip install secimport
-
- Install from source
-
git clone https://github.com/avilum/secimport.git && cd secimport python3 -m pip install poetry && python3 -m poetry install
-
Usage
To sandbox your program using the CLI, start a bpftrace program that logs all the syscalls for all the modules in your application into a file with the secimport trace command. Once you have covered the logic you would like to sandbox, hit CTRL+C or CTRL+D, or wait for the program to finish. Then, build a sandbox from the trace using the secimport build command, and run the sandbox with the secimport run command.
NAME
secimport - is a comprehensive toolkit designed to enable the tracing, construction, and execution of secure Python runtimes. It leverages USDT probes and eBPF/DTrace technologies to enhance the overall security measures.
SYNOPSIS
secimport COMMAND
DESCRIPTION
https://github.com/avilum/secimport/wiki/Command-Line-Usage
WORKFLOW:
1. secimport trace / secimport shell
2. secimport build
3. secimport run
QUICKSTART:
$ secimport interactive
EXAMPLES:
1. trace:
$ secimport trace
$ secimport trace -h
$ secimport trace_pid 123
$ secimport trace_pid -h
2. build:
# secimport build
$ secimport build -h
3. run:
$ secimport run
$ secimport run --entrypoint my_custom_main.py
$ secimport run --entrypoint my_custom_main.py --stop_on_violation=true
$ secimport run --entrypoint my_custom_main.py --kill_on_violation=true
$ secimport run --sandbox_executable /path/to/my_sandbox.bt --pid 2884
$ secimport run --sandbox_executable /path/to/my_sandbox.bt --sandbox_logfile my_log.log
$ secimport run -h
COMMANDS
COMMAND is one of the following:
build
Compiles a trace log (trace.log). Creates the sandbox executable (instrumentation script) for each supported backend It uses `create_profile_from_trace ...` and `sandbox_from_profile`.
compile_sandbox_from_profile
Generates a tailor-made sandbox that will enforce a given yaml profile/policy in runtime.
interactive
run
Run a python process inside the sandbox.
shell
Alternative syntax for secimport "trace".
trace
Traces a python process using an entrypoint or interactive interpreter. It might require sudo privilleges on some hosts.
trace_pid
Traces a running process by pid. It might require sudo privilleges on some hosts.
Stop on violation
root@1bc0531d91d0:/workspace# secimport run --stop_on_violation=true
>>> secimport run
[WARNING]: This sandbox will send SIGSTOP to the program upon violation.
RUNNING SANDBOX... ['./sandbox.bt', '--unsafe', ' -c ', '/workspace/Python-3.10.0/python', 'STOP']
Attaching 4 probes...
Python 3.10.0 (default, Apr 28 2023, 11:32:40) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system('ps')
[SECURITY PROFILE VIOLATED]: <stdin> called syscall 56 at depth 8022
^^^ STOPPING PROCESS 85918 DUE TO SYSCALL VIOLATION ^^^
PROCESS 85918 STOPPED.
Kill on violation
root@ee4bc99bb011:/workspace# secimport run --kill_on_violation
>>> secimport run
[WARNING]: This sandbox will send SIGKILL to the program upon violation.
RUNNING SANDBOX... ['./sandbox.bt', '--unsafe', ' -c ', '/workspace/Python-3.10.0/python', 'KILL']
import os
oAttaching 4 probes...
sPython 3.10.0 (default, Apr 28 2023, 11:32:40) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system('ps')
[SECURITY PROFILE VIOLATED]: <stdin> called syscall 56 at depth 8022
^^^ KILLING PROCESS 86466 DUE TO SYSCALL VIOLATION ^^^
KILLED.
SANDBOX EXITED;
Dynamic profiling - trace, build sandbox, run.
root@1fa3d6f09989:/workspace# secimport interactive
Let's create our first tailor-made sandbox with secimport!
- A python shell will be opened
- The behavior will be recorded.
OK? (y): y
>>> secimport trace
TRACING: ['/workspace/secimport/profiles/trace.bt', '-c', '/workspace/Python-3.10.0/python', '-o', 'trace.log']
Press CTRL+D to stop the trace;
Python 3.10.0 (default, Mar 19 2023, 08:34:46) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
>>>
TRACING DONE;
>>> secimport build
SECIMPORT COMPILING...
CREATED JSON TEMPLATE: policy.json
CREATED YAML TEMPLATE: policy.yaml
compiling template policy.yaml
DTRACE SANDBOX: sandbox.d
BPFTRCE SANDBOX: sandbox.bt
Now, let's run the sandbox!
- Run the same commands as before, they should run without any problem;.
- Do something new in the shell; e.g: >>> __import__("os").system("ps")
OK? (y): y
>>> secimport run
RUNNING SANDBOX... ['./sandbox.bt', '--unsafe', ' -c ', '/workspace/Python-3.10.0/python']
Attaching 5 probes...
REGISTERING SYSCALLS...
STARTED
Python 3.10.0 (default, Mar 19 2023, 08:34:46) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
>>> import os
[SECIMPORT VIOLATION]: <stdin> called syscall ioctl at depth 0
[SECIMPORT VIOLATION]: <stdin> called syscall ioctl at depth 0
For more detailed usage instructions, see the Command-Line Usage page.
nsjail support (seccomp)
Beside the sandbox that secimport builds,
The secimport build
command creates an nsjail sandbox with seccomp profile for your traced code.
nsjail
enables namespace sandboxing with seccomp on linux
secimport
automatically generates seccomp profiles to use with nsjail
as executable bash script.
It can be used to limit the syscalls of the entire python process, as another layer of defence.
Python API
Instead of CLI, you can also use secimport
by replacing "import
" with "secimport.secure_import
" for selected modules. See the Python Imports example for more details.
Docker
The quickest way to evaluate secimport
is to use our Docker container, which includes bpftrace
(ebpf
) and other plug-and-play examples.
Examples
The Sandbox Examples page contains basic and advanced real-world examples.
Contributing
For information on how to contribute to secimport
, see the Contributing guide.
Roadmap
See the Roadmap for the planned features and development milestones.
Changelog
See the Changelog for development progress and existing features.
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
Hashes for secimport-0.9.2-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 73d68de9d644ed8e9ac8af6146fa30cbcbd11461a679e53bfd8a425f7df35edf |
|
MD5 | f78c19cd1fff20062d7f16bf1a2c8ee1 |
|
BLAKE2b-256 | b5a9d2a31f3465248c98e90adad62b38f73e411b321d3f554cf81c604cb8c5ac |