3

I've seen a couple other posts about people trying to run untrusted user inputted code into a eval or exec statement. My implementation checks the code before hand for any import statements, makes sure there are no builtins on the exec statement and clears all the global variables. I also put checks in place for the use of __ in the code to make sure users couldn't input dangerous code that way

Does this fix the problem, or are there other ways of users being able to import dangerous modules and breaking out of the shell or doing some malicious?

  • @immibis what if I don't allow any imports at all? Is there any vulnerability in base python that can be abused? – adammoyle Apr 12 '18 at 1:14
  • 5
    How about getattr(getattr(globals()['_'+'_built'+'ins_'+'_'], '_'+'_imp'+'ort_'+'_')('os'), 'sys'+'tem')("echo hello world")? – immibis Apr 12 '18 at 1:45
  • run the code in a subprocess, which you run as a user with limited rights, and with some cpu/disk/network quotas set. chroot jail maybe – Bwmat Apr 12 '18 at 6:31
  • 3
    As @immibis has demonstrated, in a dynamic language like Python it is impossible to ensure a script is 'safe' just by scanning it for certain substrings. The only real solution is to isolate the process in some way like Bwmat suggests. – Sean Burton Apr 12 '18 at 13:38
2

Python doesn't have a security model that allows you to securely execute untrusted code within your program. Even in languages that do have such security models (like Java) there tend to be countless bugs that render usage of this security model questionable.

There are two reasonable approaches to this security problem:

  • use security features of the operating system, e.g. seccomp/capabilities/namespaces in Linux.

  • do not allow unrestricted code, but instead interpret a domain-specific language or parametrize your input with a simple data model. For many problem domains, configuration instead of code is a reasonable approach. It may also be feasible to include a sandboxed virtual machine, e.g. a JavaScript environment.

The third solution is probably the most realistic: adapt your application's security model to the reality that it will run code you didn't write. E.g. if users run your software themselves, then any plugins they write are their problem. This is fine, as long as you document this possibility.

Note that merely disallowing imports is not helpful as long as you provide any user-defined objects to the untrusted code. Using reflection, it is then often possible to access any variables from the module where it was defined, including a full set of builtins or other already imported modules.

1

The closest thing is probably PyPy's sandboxing feature: http://doc.pypy.org/en/latest/sandbox.html

This doesn't prevent resource exhaustion however, which you could further limit with the tools amon mentioned.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.