Skip to main content

Safely execute arbitrary Python codes using nsjail.

Project description

Python Safe Eval

Safely execute arbitrary python code using nsjail.

tl;dr

import PythonSafeEval
from pathlib import Path

try:
    sf = PythonSafeEval.SafeEval(version="3.8", modules=["numpy"])
    print(sf.eval(code='print("Hello World")').stdout)
    print(sf.execute_file(filename=Path(__file__).parent / "test_numpy.py").stdout)
except:
    print("error")

Installation

Install via pip:

pip install PythonSafeEval

Or clone this repo.

Requirements

Python >= 3.6. No additional package is needed.

To create the sandbox, the Python process must have access to docker and git.
Notice that giving access to docker daemon grants privileges equivalent to the root user, so be careful.

Usage

First, initialize the sandbox. The version and modules stand for, well, the version of Python and the modules to install. tmp_dir stands for the directory to write temporary files. The package would create a directory in the supplied path, and write the code to that directory. If tmp_dir is not supplied, a temporary directory would be created. In termination, the directory would be removed.

sf = PythonSafeEval.SafeEval(version="3.8", modules=["numpy"], tmp_dir='~/tmp/')

Notice that, since all scripts to be executed is stored in tmp_dir, strict control of permission is recommended.

Next, to run a script, we have to method: supply a string or a file.
To supply a string, use sf.eval, which returns a subprocess.CompletedProcess.

r = sf.eval(code='print("Hello World")')

To supply a file, use sf.execute_file, which, again, returns a subprocess.CompletedProcess.

r = sf.execute_file(filename=Path(__file__).parent / "test_numpy.py")

To limit the execution time, use the time_limit parameter. The default value is 0, i.e., no limit.

r = sf.eval(code='print("Hello World")', time_limit=10)

How it works

During initialization, we first write a Dockerfile specifying Python version and modules, create a Docker image, and create a Docker container. We also create a temporary directory and mount the directory in the container. Whenever a script is supplied, we copy the script to a shared directory and use nsjail <some parameters> python3 <your script> to run the script. Why nsjail in Docker? Because Docker container is not a VM or a sandbox. In the destructor, the container is stopped and removed, the image is removed, and the temporary directory is also removed.

Security Issues

There are some security issues that all users should keep in mind.

  1. Giving access to docker daemon grants privileges equivalent to the root user, so it's a good idea to separate the PythonSafeEval and the main application and limit the access between the two.
  2. The code would be stored in the temporary directory, and the attacker may modify the file before PythonSafeEval execute it. While generally in the sandbox no harm can be done, the attacker could still paralyze the machine through infinite loops or heavy calculations. Therefore, set the time_limit when possible.
  3. PythonSafeEval uses nsjail, which should be safe, but there's no guarantee.

Finally, there's no guarantee that this package is safe. Read the license for more information.

Use in Docker

If your Python application is running in a Docker container, given that Docker can't be run in a Docker container (actually you can, but DON'T DO THAT PLEASE), we have to let the container access the docker daemon.

docker run <something> -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v /.jailfs:/.jailfs

Note that the path of the temporary directory inside the container and outside the container should be the same, e.g., /.jailfs:/.jailfs.

License

MIT License.

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

PythonSafeEval-0.0.1.tar.gz (4.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

PythonSafeEval-0.0.1-py3-none-any.whl (5.9 kB view details)

Uploaded Python 3

File details

Details for the file PythonSafeEval-0.0.1.tar.gz.

File metadata

  • Download URL: PythonSafeEval-0.0.1.tar.gz
  • Upload date:
  • Size: 4.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/51.1.2 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.9.1

File hashes

Hashes for PythonSafeEval-0.0.1.tar.gz
Algorithm Hash digest
SHA256 54dac370d8fd60e1af11f65101790356e50598cea51b850c716ac74a0eefe36f
MD5 b9ca1091f45b92d19811adac1377094b
BLAKE2b-256 ac35c015d62ada64a2f59c829bcb1c98377bcd56faf489387153dc68393e9f55

See more details on using hashes here.

File details

Details for the file PythonSafeEval-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: PythonSafeEval-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 5.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/51.1.2 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.9.1

File hashes

Hashes for PythonSafeEval-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4847f736a82aa6edc3ad8b1a51253be290ba9015f03b8bac3983a0e39c209cdc
MD5 8d86aa0f496037783e6171ad405485f6
BLAKE2b-256 468fea4308c4a9fb4b5b45e92ae3a7ef1e2b711e9850d1bf67a0cf0c7892f7ca

See more details on using hashes here.

Supported by

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