Skip to main content

A safe eval using Abstract Syntax Tree

Project description

Introduction

The astrun package is to provide a "relative" secure way to evaluate Python expressions similar to Python's eval, as the builtin eval and exec are insecure and can be exploited in many ways.

This package is very small and need no dependencies. You can just copy, modify and use. Happy Programming.

Use Cases

  • you want to build a web calculator do simple math calculations or string operations.
  • you want to give certain users high flexibility to configure some conditions. E.g.
    • to determine if a file path is good for further process.
    • to customize string transformations.

Examples

from astrun import Astrun

Astrun.eval("1 in {i for i in range(10) if i % 2 == 1}")  # return True

Astrun.eval("__import__('os')")  # will through PermissionError
Astrun.eval("open('file', 'w')")  # will through PermissionError

For more examples, see the test code in test and the source code in src.

NOTICE: this library can only be used in Python >= 3.11 because it used * unpacking in subscription which is a feature introduced in Python 3.11. If you would like to use it in earlier Python versions, change the code in Astrun.visit_Subscript to other ways of unpacking.

How It Works

Astrun evaluates the given code text as instructions only, and the execution is done by Astrun's own code:

  • Astrun uses the ast library to parse the code text to an Abstract Syntax Tree (AST).
  • The tree is then executed by translating each node back to Astrun's own Python code.
    • The execution is within a namespace that excludes the dangerous builtins functions such as eval, exec,globals, __import__, etc.
    • Advanced AST nodes, such as function and class definition, are blocked.
    • Private or dunder attributes' access of any object is prohibited.

However, using Astrun alone is still not secure for a server to execute arbitrary code texts, because a user can still provide code that

  • overloads the CPU. e.g. 1024**1024**1024**1024
  • causes memory overflow. e.g. [0] * (1024*1024*1024*1024)
  • exploits other ways to access system IO or network

Therefore, IsolatedEnv is provided (ATTENTION: Linux Only, not even Mac OS) to isolate any code execution in a separated constraint Python Process:

  • the total memory is limited.
  • the total CPU time is limited.
  • file descriptor creation is blocked.
  • subprocess creation is blocked.
  • the response time of a single execution is timed.
  • if any restriction violated the Process is terminated.

E.g.

from astrun import Astrun, IsolatedEnv


class AstrunIsolatedEnv(IsolatedEnv):
    @staticmethod
    def _run(*args):
        return Astrun.eval(*args)


with AstrunIsolatedEnv() as env:
    assert env("1+1") == 2

Safety Warnings

It is NOT guaranteed that arbitrary code can be executed harmlessly by using Astrun inside a IsolatedEnv . Since users provided the code text, they may find loopholes to bypass the restrictions and Python is nothing short of convenient loopholes.

Therefore, if you use astrun to run arbitrary users code text, make sure the OS account to run the process is restricted (no sudo, no access to important files, etc.).

It is better to only expose astrun to the responsible users, such as the admins of your webapp, and log the users and the code text they provide.

Last But Not Least

I searched the web for a long time for a package like astrun but cannot find one, so I made my own. If you find a loophole of astrun, please open an issue and submit it, so that it can be blocked.

Or maybe it cannot be blocked. Then, it explains why no such package exists. An alternative way is to run JavaScript in Python, since JavaScript has no IO access, so it is IO safe. However, import a JavaScript engine into a Python program is likely an overkill.

LICENSE

Can you believe it is "MIT"!

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

astrun-1.0.4.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

astrun-1.0.4-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file astrun-1.0.4.tar.gz.

File metadata

  • Download URL: astrun-1.0.4.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.1

File hashes

Hashes for astrun-1.0.4.tar.gz
Algorithm Hash digest
SHA256 f93a0ea6e2f11254afcd4ef6537e63dde3f13bacfa6d2936e1b4fc882c4deaa4
MD5 53a19e71ace2acd3e1ca7a402a2c3cd9
BLAKE2b-256 f0d4827bfcde97ade2d6eedde6a2f86801d8fedee462c08620a8b40d888686f4

See more details on using hashes here.

File details

Details for the file astrun-1.0.4-py3-none-any.whl.

File metadata

  • Download URL: astrun-1.0.4-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.1

File hashes

Hashes for astrun-1.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 e01c82620ba85add901bcb76ebfd2c4659449b473addaa1bfd90e6541a576340
MD5 d04516a246dd1d2ebf784e52bdf72785
BLAKE2b-256 a7e0c8a0eee9cd622c720ddf8c1acd2ee8cb91ee05fb3942b869ab45e55e4419

See more details on using hashes here.

Supported by

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