A sandbox/supervisor for python modules.
Project description
secimport
secimport
is a sandbox toolkit, that traces your application and grants privilleges per module in your code.
By doing so, secimport
enhances runtime security, giving you the ability to choose the privilleges for:
- All of your code - global privilleges (like seccomp, apparmor, firejail, etc.)
- 3rd party dependencies
- That can be added/modified without you knowing, to avoid supply chain attacks.
- Open-Source packages
- You don't have control over them, and keeping it up-to-date cannot be guaranteed.
It uses backends like bpftrace (eBPF) and dtrace under the hood, making it cross-platform.
How is works?
secimport
uses USDT (Userland Statically Defined Tracing) probes in the runtime (Python interpreter for example) using eBPF and dtrace instrumentation scripts.
You can use secimport
to:
- Trace which syscalls are called by each module in your code, or by your entire application.
- Restrict specific modules/packages inside your production environment like 3rd party, open source or code from untrusted source.
- Audit the flow of your python application at user-space/os/kernel level.
- Kill or audit upon violoation of your specified behavior. Killing is optional.
Quick Start
There are several methods to create and run a sandbox:
- By modifying your imports
- Inside your code using
module = secimport.secure_import('module_name', ...)
.- Replacing the regular
import
statement withsecure_import
- Only modules that were imported with
secure_import
will be traced.
- Replacing the regular
- Inside your code using
- By running it as a parent process for your application
- Generate a YAML policy from your code, by specifying the modules and the policy you want, for every module that you would like to restrict in any way.
- Convert that YAML policy to dscript/bpftrace sandbox code.
- Run you tailor-made sandbox
- Use
dtrace
orbpftrace
to run your main python application, with your tailor-made sandbox. - No need for
secure_import
, you can keep using regularimport
s and not change your code at all.
- Use
- Generate a YAML policy from your code, by specifying the modules and the policy you want, for every module that you would like to restrict in any way.
Docker
The easiest way to try secimport is by using our Docker for MacOS and Linux. It includes python, secimport and bpftrace backend.
dtrace
backend is not available in docker, and can be tried directly on the compatible hosts ( Mac OS , Windows, Solaris, Unix, some Linux distributions).
References:
-
Read about the available backends in secimport:
- https://www.brendangregg.com/DTrace/DTrace-cheatsheet.pdf
dtrace
- https://www.brendangregg.com/blog/2018-10-08/dtrace-for-linux-2018.html
bpftrace
(dtrace 2.0) that uses LLVM and compiled our script to BCC.
- https://www.brendangregg.com/DTrace/DTrace-cheatsheet.pdf
-
Guides
- Tracing Processes Guide
- Installation
- Mac OS Users - Disabling SIP (System Intergity Protection)
- F.A.Q
Example Use Cases
EXAMPLES.md contains advanced usage and many interactive session examples: YAML profies, networking, filesystem, processing blocking & more.
Simple Usage
- Running Sandbox Using Python Imports
secimport
CLI usage- The easiest option to start with inside docker.
python -m secimport.cli --help
- See YAML Profiles Usage>
How pickle can be exploited in your 3rd party packages (and how to block it)
# Not your code, but you load and run it frmo 3rd some party package.
import pickle
class Demo:
def __reduce__(self):
return (eval, ("__import__('os').system('echo Exploited!')",))
pickle.dumps(Demo())
b"\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x04eval\x94\x93\x94\x8c*__import__('os').system('echo Exploited!')\x94\x85\x94R\x94."
# Your code, at some day...
pickle.loads(b"\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x04eval\x94\x93\x94\x8c*__import__('os').system('echo Exploited!')\x94\x85\x94R\x94.")
Exploited!
0
With secimport
, you can control such action to do whatever you want:
import secimport
pickle = secimport.secure_import("pickle")
pickle.loads(b"\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x04eval\x94\x93\x94\x8c*__import__('os').system('echo Exploited!')\x94\x85\x94R\x94.")
[1] 28027 killed ipython
A log file is automatically created, containing everything you need to know:
$ less /tmp/.secimport/sandbox_pickle.log
@posix_spawn from /Users/avilumelsky/Downloads/Python-3.10.0/Lib/threading.py
DETECTED SHELL:
depth=8
sandboxed_depth=0
sandboxed_module=/Users/avilumelsky/Downloads/Python-3.10.0/Lib/pickle.py
TERMINATING SHELL:
libsystem_kernel.dylib`__posix_spawn+0xa
...
libsystem_kernel.dylib`__posix_spawn+0xa
libsystem_c.dylib`system+0x18b
python.exe`os_system+0xb3
KILLED
:
More examples are available at EXAMPLES.md.
Roadmap
- ✔️ Allow/Block list configuration
- ✔️ Create a .yaml configuration per module in the code
- ✔️ Use secimport to compile that yml
- ✔️ Create a single dcript policy
- ✔️ Run an application with that policy using dtrace, without using
secure_import
- ✔️ Add eBPF basic support using bpftrace
- ✔️ bpftrace backend tests
- ✔️ Implement all python supported USDT probes:
- ✔️ import__find__load__start
- ✔️ import__find__load__done
- ✔️ line
- Extandible Language Template
- Implement bpftrace probes for new languages
- Go support (bpftrace/dtrace hooks)
- Implement a template for golang's call stack
- Node support (bpftrace/dtrace hooks)
- Implement a template for Node's call stack and event loop
- Multi Process support: Use current_module_str together with thread ID to distinguish between events in different processes
- Update all linux syscalls in the templates (filesystem, networking, processing) to improve the sandbox blocking of unknowns.
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.6.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 84475f857c1295114b3bc8526eda4c42818427eac23edb6c7453e590d599676e |
|
MD5 | fbc03494c86d21439064667345e80bd2 |
|
BLAKE2b-256 | 9b2367d835ae8fc6e3dbb03dc99678d57b86d4867ea5f361b923bbb18a7d7488 |