Package: secimport
Table of Contentsgenerated withDocTocsecimportThe Tailor-Made Sandbox for Your ApplicationThe problemThe solutionInstallationWith DockerWithout DockerUsageStop on violationKill on violationDynamic profiling - trace, build sandbox, run.nsjail support (seccomp)Python APIDockerExamplesContributingRoadmapChangelogsecimportThe Tailor-Made Sandbox for Your Applicationsecimport 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):secimport + Dtracesecimprt + eBPF + PyTorchsecimport + eBPF + FastAPIThe problemTraditional tools like seccomp or AppArmor enforce syscalls for the entire process.Something likeallowed_syscalls=["read","openat","bind","write"], which is great, but not enough for python's attack surface.The solutionsecimportis 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 likethis.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.secimportis 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 likelog4shell. 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 SourcesModels 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 ImpactHas negligible performance impact and is production-ready thanks to eBPF. Check out thePerformancebenchmarks.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.InstallationTested on Ubuntu, Debian, Rocky (Linux x86/AMD/ARM) and MacOS in (x86/M1). If you run on MacOS you will need todisable SIP for dtrace.With DockerFor quicker evaluation, we recommend using theSecimport Docker Imageinstead of self-installing.Build and run the Docker container with a custom kernel that matches your existing OS kernel version:cd docker/ && ./build.sh && ./run.shA temporary container will be created, and you will be logged in as the root user.Without DockerInstall python with USDT probes byconfiguring it with '--dtrace'Install one of the backends:eBPF or DTrace.Install secimportInstall from pypipython3 -m pip install secimportInstall from sourcegit clone https://github.com/avilum/secimport.git && cd secimport
python3 -m pip install poetry && python3 -m poetry installUsageTo 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.NAMEsecimport-isacomprehensivetoolkitdesignedtoenablethetracing,construction,andexecutionofsecurePythonruntimes.ItleveragesUSDTprobesandeBPF/DTracetechnologiestoenhancetheoverallsecuritymeasures.

SYNOPSISsecimportCOMMAND

DESCRIPTIONhttps://github.com/avilum/secimport/wiki/Command-Line-UsageWORKFLOW:1.secimporttrace/secimportshell2.secimportbuild3.secimportrunQUICKSTART:$secimportinteractiveEXAMPLES:1.trace:$secimporttrace$secimporttrace-h$secimporttrace_pid123$secimporttrace_pid-h2.build:# secimport build$secimportbuild-h3.run:$secimportrun$secimportrun--entrypointmy_custom_main.py$secimportrun--entrypointmy_custom_main.py--stop_on_violation=true$secimportrun--entrypointmy_custom_main.py--kill_on_violation=true$secimportrun--sandbox_executable/path/to/my_sandbox.bt--pid2884$secimportrun--sandbox_executable/path/to/my_sandbox.bt--sandbox_logfilemy_log.log$secimportrun-h

COMMANDSCOMMANDisoneofthefollowing:buildCompilesatracelog(trace.log).Createsthesandboxexecutable(instrumentationscript)foreachsupportedbackendItuses`create_profile_from_trace...`and`sandbox_from_profile`.compile_sandbox_from_profileGeneratesatailor-madesandboxthatwillenforceagivenyamlprofile/policyinruntime.interactiverunRunapythonprocessinsidethesandbox.shellAlternativesyntaxforsecimport"trace".traceTracesapythonprocessusinganentrypointorinteractiveinterpreter.Itmightrequiresudoprivillegesonsomehosts.trace_pidTracesarunningprocessbypid.Itmightrequiresudoprivillegesonsomehosts.Stop on violationroot@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 violationroot@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#secimportinteractive

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 traceTRACING: ['/workspace/secimport/profiles/trace.bt', '-c', '/workspace/Python-3.10.0/python', '-o', 'trace.log']PressCTRL+Dtostopthetrace;Python3.10.0(default,Mar192023,08:34:46)[GCC9.4.0]onlinux
Type"help","copyright","credits"or"license"formoreinformation.
>>>importthis
>>>TRACINGDONE;>>>secimportbuild

SECIMPORTCOMPILING...

CREATEDJSONTEMPLATE:policy.json
CREATEDYAMLTEMPLATE:policy.yaml
compilingtemplatepolicy.yaml
DTRACESANDBOX:sandbox.d
BPFTRCESANDBOX:sandbox.btNow, let's run the sandbox!-Runthesamecommandsasbefore,theyshouldrunwithoutanyproblem;.-Dosomethingnewintheshell;e.g:>>>__import__("os").system("ps")OK?(y):y>>>secimportrunRUNNINGSANDBOX...['./sandbox.bt','--unsafe',' -c ','/workspace/Python-3.10.0/python']Attaching5probes...REGISTERINGSYSCALLS...STARTEDPython3.10.0(default,Mar192023,08:34:46)[GCC9.4.0]onlinuxType"help","copyright","credits"or"license"formoreinformation.>>>importthis>>>importos[SECIMPORTVIOLATION]:<stdin>calledsyscallioctlatdepth0[SECIMPORTVIOLATION]:<stdin>calledsyscallioctlatdepth0For more detailed usage instructions, see theCommand-Line Usagepage.nsjail support (seccomp)Beside the sandbox that secimport builds,Thesecimport buildcommand creates annsjailsandbox with seccomp profile for your traced code.nsjailenables namespace sandboxing with seccomp on linuxsecimportautomatically generates seccomp profiles to use withnsjailas executable bash script.
It can be used to limit the syscalls of the entire python process, as another layer of defence.Python APIInstead of CLI, you can also usesecimportby replacing "import" with "secimport.secure_import" for selected modules. See thePython Importsexample for more details.DockerThe quickest way to evaluatesecimportis to use ourDocker container, which includesbpftrace(ebpf) and other plug-and-play examples.ExamplesTheSandbox Examplespage contains basic and advanced real-world examples.ContributingFor information on how to contribute tosecimport, see theContributingguide.RoadmapSee theRoadmapfor the planned features and development milestones.ChangelogSee theChangelogfor development progress and existing features.