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 throw PermissionError
Astrun.eval("open('file', 'w')") # will throw 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:
Astrunuses 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.- see the Astrun's namespace attribute. Common built-ins are included and the "re" package is included.
- Advanced AST nodes, such as function and class definition, are blocked.
- Private or dunder attributes' access of any object is prohibited.
- The execution is within a namespace that excludes the dangerous builtins functions such as
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"!
Metadata
Release files for astrun 1.0.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| astrun-1.0.8.tar.gz | 9.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| astrun-1.0.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.4 kB
Release files / astrun-1.0.8.tar.gz
| Download URL | astrun-1.0.8.tar.gz |
|---|---|
| Size | 9.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eb304897232e258e81484ddbff45f75086ca3780a4484398532987f00ef23744
|
|
BLAKE2b-256 checksum How to use checksums |
b8b463f51b98b33ad28c67599ec18e9c9aa970797ddc2b5c8e69e7864af798b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.12.1
|
Release files / astrun-1.0.8-py3-none-any.whl
| Download URL | astrun-1.0.8-py3-none-any.whl |
|---|---|
| Size | 8.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
80a8270851cffb3ad25cd9e4a6812bbfc01fbbb5bc00079b5b31383a0aa3386c
|
|
BLAKE2b-256 checksum How to use checksums |
fed2c57a02e4fcb361a34840f05ff93304635ab0f18eb2af2452ebd0c521256e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.12.1
|
Security for astrun 1.0.8
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.