简体   繁体   中英

How can I safely run untrusted python code?

Here is the scenario, my website has some unsafe code, which is generated by website users, to run on my server.

I want to disable some reserved words for python to protect my running environment, such as eval , exec , print and so on.

Is there a simple way (without changing the python interpreter, my python version is 2.7.10) to implement the feature I described before?

Many thanks.

Disabling names on python level won't help as there are numerous ways around it. See this and this post for more info. This is what you need to do:

For CPython, use RestrictedPython to define a restricted subset of Python.

For PyPy, use sandboxing . It allows you to run arbitrary python code in a special environment that serializes all input/output so you can check it and decide which commands are allowed before actually running them.

Since version 3.8 Python supports audit hooks so you can completely prevent certain actions:

import sys

def audit(event, args):
    if event == 'compile':
        sys.exit('nice try!')

sys.addaudithook(audit)

eval('5')

Additionally, to protect your host OS, use

  • either virtualization (safer) such as KVM or VirtualBox

  • or containerization (much lighter) such as lxd or docker

In the case of containerization with docker you may need to add AppArmor or SELinux policies for extra safety. lxd already comes with AppArmor policies by default.

Make sure you run the code as a user with as little privileges as possible.

Rebuild the virtual machine/container for each user.

Whichever solution you use, don't forget to limit resource usage (RAM, CPU, storage, network). Use cgroups if your chosen virtualization/containerization solution does not support these kinds of limits.

Last but not least, use timeouts to prevent your users' code from running forever.

One way is to shadow the methods:

def not_available(*args, **kwargs):
    return 'Not allowed'

eval = not_available
exec = not_available
print = not_available

However, someone smart can always do this:

import builtins
builtins.print('this works!')

So the real solution is to parse the code and not allow the input if it has such statements (rather than trying to disable them).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM