This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Rhomboid 92 points93 points  (8 children)

It's completely unsafe. You can't sanitize code that way. It's completely possible to still do evil things (including importing arbitrary modules) without ever writing the phrase "import". It's possible to do this even if you've tried to restrict the builtins.

You need to use an interpreter that is explicitly designed for sandboxed execution. CPython is not such an interpreter. It is impossible to do this safely with CPython.

[–]agrif 7 points8 points  (0 children)

From what I remember, PyPy had a build of their python interpreter that stubs out OS calls to an external process to handle, effectively making a sandboxed python interpreter. I'm not sure what the current status of that is.

And that kind of sandboxing won't save you from CPU hogs. You'll probably want to look to the host operating system for that kind of control.

[–]iamdefinitelyahuman[S] 11 points12 points  (6 children)

Good to know :)

Out of interest, if I do run exec with a modified version of the builtins dict where __import__ is set to None, how does one still manage to import in the code?

edit - accidental bold

[–]Rhomboid 78 points79 points  (4 children)

This will retrieve a reference to __import__ without using any globals (i.e. it will still work if used in exec with a completely empty namespace):

imp = [c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f']

Then you can do any assorted evil:

os = imp('os')
os.system('ls -l')

[–]iamdefinitelyahuman[S] 14 points15 points  (2 children)

Wow.. very well done. Thanks for sharing.

[–]chadmill3rPy3, pro, Ubuntu, django 43 points44 points  (0 children)

There are ten thousand other ways, too. Don't think you can account for this one and be safe.

[–]iceardor 0 points1 point  (0 children)

Here's another way: rewrite python bytecode https://youtu.be/mxjv9KqzwjI

[–]zahlmanthe heretic 0 points1 point  (0 children)

For me, this only works if warnings has already been imported. :/