0

I have a project where a user can provide a python script that will be execute on the server to verify if the script is valid according to some criteria. I use the exec function to execute the code but it's vulnerable. User can use the os module in the script.

Is there a way to prevent command injection ? By preventing some modules to be used in exec ? Or another way to execute python code without risking injections ?

Thanks !

Lilian
  • 21
  • 1
    here's a guide that has tips: https://realpython.com/python-exec/ a big tip though, is: if you are using `exec`, make it run on the enduser/submitter's computer, not on your server, or you will be vulnerable. sounds like that is exactly what you want to do, so will probably carry some risk – scotscotmcc Sep 08 '22 at 22:09
  • 1
    Even if you prevent OS command injection, it could still uses python built-in functions and libraries to cause extensive problems. User-supplied code should be run in a temporary virtual machine to prevent them from doing damage. – Barmar Sep 08 '22 at 22:11
  • 2
    Safe exec is really really hard in python, because a series of attribute accesses from innocuous types like `str` gets you to dangerous classes and modules – Jiří Baum Sep 08 '22 at 22:18
  • @JiříBaum, do you have a link/search term? Curious to see how that works. – Kaia Sep 08 '22 at 23:10
  • The comments on [this answer](https://stackoverflow.com/a/3068259/683329) suggest `().__class__.__base__.__subclasses__()` which gives all the classes and then picking any class by name; they use it to construct a `code` object. [This reddit comment](https://www.reddit.com/r/Python/comments/hftnp/comment/c1v372r/) uses the same trick to get back to the `builtins` module. I think I've seen others that take a more direct path from `str` to opening a file, although I can't quickly find it. – Jiří Baum Sep 09 '22 at 00:12
  • On another level, Python used to come with a [`rexec` module](https://docs.python.org/2/library/rexec.html) in the standard library, which has been deprecated and removed; even the authors of the standard library, with all the expertise and the relationship with python core, could not find a way to get it to work. Python is just too dynamic and has too much introspection available. – Jiří Baum Sep 09 '22 at 00:23
  • So, the question is what to do next; part of that depends on who the users are and what criteria you want to check. It's possible to safely compile code to an AST, then check some properties from that; static analysis, basically. Are the criteria amenable to static checking? – Jiří Baum Sep 09 '22 at 00:30
  • The other way is to go the system way, with chroot jails and docker containers and VMs; those have their own challenges, but they have been done more successfully – Jiří Baum Sep 09 '22 at 00:36
  • @JiříBaum have you a link or something on the way to do this with chroot jails, docker containers or VMs ? – Lilian Sep 09 '22 at 05:47
  • @JiříBaum I want to check if a function exists in the code and get the results of that function if exists – Lilian Sep 09 '22 at 05:48
  • Easy enough to check whether a function exists; however, getting the result would involve running the code, at which point it's vulnerable – Jiří Baum Sep 09 '22 at 05:53

0 Answers0