Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

disallow access to filesystem inside exec and eval in Python

I want to disallow access to file system from clients code, so I think I could overwrite open function

env = {
   'open': lambda *a: StringIO("you can't use open")
}

exec(open('user_code.py'), env)

but I got this

unqualified exec is not allowed in function 'my function' it contains a 
nested function with free variables

I also try

 def open_exception(*a):
     raise Exception("you can't use open")
 env = {
     'open': open_exception
 }

but got the same Exception (not "you can't use open")

I want to prevent of:

executing this:

"""def foo():
     return open('some_file').read()
print foo()"""

and evaluate this

"open('some_file').write('some text')"

I also use session to store code that was evaluated previously so I need to prevent of executing this:

"""def foo(s):
   return open(s)"""

and then evaluating this

"foo('some').write('some text')"

I can't use regex because someone could use (eval inside string)

"eval(\"opxx('some file').write('some text')\".replace('xx', 'en')"

Is there any way to prevent access to file system inside exec/eval? (I need both)

like image 876
jcubic Avatar asked Nov 29 '22 03:11

jcubic


1 Answers

There's no way to prevent access to the file system inside exec/eval. Here's an example code that demonstrates a way for the user code to call otherwise restricted classes that always works:

import subprocess
code = """[x for x in ().__class__.__bases__[0].__subclasses__() 
           if x.__name__ == 'Popen'][0](['ls', '-la']).wait()"""
# Executing the `code` will always run `ls`...
exec code in dict(__builtins__=None)

And don't think about filtering the input, especially with regex.

You might consider a few alternatives:

  1. ast.literal_eval if you could limit yourself only to simple expressions
  2. Using another language for user code. You might look at Lua or JavaScript - both are sometimes used to run unsafe code inside sandboxes.
  3. There's the pysandbox project, though I can't guarantee you that the sandboxed code is really safe. Python wasn't designed to be sandboxed, and in particular the CPython implementation wasn't written with sandboxing in mind. Even the author seems to doubt the possibility to implement such sandbox safely.
like image 69
Rosh Oxymoron Avatar answered Dec 05 '22 14:12

Rosh Oxymoron