Executing untrusted code

  • Thread starter Emanuele D'Arrigo
  • Start date
E

Emanuele D'Arrigo

Greetings everybody,

I've been reading and mulling about python and security, specifically
in terms of executing code that may or may not be trustworthy. I
understand that libraries such as Rexec and Bastion are now deprecated
because they have known vulnerabilities that may be exploited to
circumvent the restrictions imposed.

So, am I right in understanding that is not possible to execute a
piece of code in a way that limits the objects and attributes that it
can access or that limits its access to file system and sockets? Are
there best practices to at least minimize some of the risks associated
with untrusted code execution?

And whatever happened to this:

http://sayspy.blogspot.com/2007/05/i-have-finished-securing-python.html

seemed to be a step forward in the right direction!

Manu
 
N

Nobody

Are
there best practices to at least minimize some of the risks associated
with untrusted code execution?

Yes: don't execute it. Failing that, run the Python interpreter within a
sandbox.

If you want to support restricted execution within a language, it has to
be built into the language from day one. Trying to bolt it on later is a
fool's errand.
 
E

Emanuele D'Arrigo

Sorry for digging this back from the grave.
I've had to chew on it for a little while.

If you want to support restricted execution within a language, it
has to be built into the language from day one. Trying to bolt it > on later is a fool's errand.

Fair enough. In this context, let's say I do this:

import __builtin__
import imp
originalBuiltins = imp.new_module("OriginalBuiltins")

def readOnlyOpen(filename):
return originalBuiltins.open(filename, "r")

__builtin__.open = readOnlyOpen

exec(anUntrustedString, {})

In what ways would the untrusted string be able to obtain the
original, built-in open function and open a file for writing?

Manu
 
R

Rami Chowdhury

They could, of course, use the file object constructor directly, e.g.:
f = file("/etc/passwd", "w")
 
S

Steven D'Aprano

Fair enough. In this context, let's say I do this:

import __builtin__
import imp
originalBuiltins = imp.new_module("OriginalBuiltins")

def readOnlyOpen(filename):
return originalBuiltins.open(filename, "r")

__builtin__.open = readOnlyOpen


Have you actually tested this? I don't think it works the way you think
it does.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'open'


So your strategy fails to provide read-only file access.

But moving on...
In what ways would the untrusted string be able to obtain the original,
built-in open function and open a file for writing?

That's hardly even a challenge.
.... reload(__builtin__)
.... open('junk', 'w').write('a')
.... """'a'


Not only have I broken your "read only" open within the call to exec, but
I've broken it outside as well. With a little bit more effort, I could
probably save and restore the open, so that my untrusted string could
write to files inside the exec(), but code outside of the exec() would
still see the readOnlyOpen.
 
E

Emanuele D'Arrigo

Christian, Rami and Steven, thank you all for your help. It wasn't
meant to be a challenge, I knew it ought to be easily breakable. I'm
no hacker and it just helps to have some examples to better understand
the issue.

On Aug 20, 7:42 pm, Steven D'Aprano <st...@REMOVE-
On a related topic, you should read this post here:
http://tav.espians.com/a-challenge-to-break-python-security.html

Indeed I did read the post and my minimalistic test was inspired by
some of the code in it (I didn't know you could replace the
builtins!). Tav's effort kinda of ended nowhere though. My
understanding of it is that it hasn't been broken and that Tav has
submitted a patch to secure some of python's innards. But

Steven, you are perfectly right, I didn't test it and I missed the
crucial part in which I store the __builtins__ dictionary in the
dictionary of the new originalBuiltins module. My bad. Still, you did
understand my intentions and did give me a simple example of how it
could be broken. Thank you.

-However- I would suggest that conceptually the "award" goes to
Christian. ;)

In the same way the open builtin function can be replaced or removed,
also reload, file, __import__, exec, execfile and any other
potentially "unsafe" builtin can be replaced with safer versions. Or
not?

Christian's solution though, seems to be much trickier to evade. Can
the object class be replaced at runtime with a version that does not
provide a way to reach its subclasses?

Manu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top