1

Is there pure python code that can break out of an execfile with local and global arguments?

I was under the impression that nothing is "private" in python. But if I execute a piece of python code (with execfile) and capture the execution results in local and global namespace arguments, I am unaware of how you'd grab the scope of the main executable.

Thanks, Chenz

Crazy Chenz
  • 12,650
  • 12
  • 50
  • 62
  • 1
    What do you mean by "break out"? – Tim Peters Oct 29 '13 at 01:49
  • I guess I'm thinking when you run something like execfile(script, {}, {}), its almost like running a sandbox (for pure python). So from this psuedo sandbox context, how can I modify my caller's environment? – Crazy Chenz Oct 29 '13 at 01:51
  • A sandbox is difficult. [See this answer](http://stackoverflow.com/questions/3068139/how-can-i-sandbox-python-in-pure-python). – Tim Peters Oct 29 '13 at 02:00
  • I'm looking for potential for a trusted user to do something "clever" that results in subverting the intention of the mechanism. – Crazy Chenz Oct 29 '13 at 02:00
  • @TimPeters I'm not trying to create a sandbox for security... – Crazy Chenz Oct 29 '13 at 02:04
  • 2
    @CrazyChenz, then please edit your question to explain what you *are* trying to accomplish. It's clear as mud ;-) – Tim Peters Oct 29 '13 at 02:06
  • The try: raise except: is a good enough answer for me. Its pure python and gets me the callers frame. Still would be nice to see a proof of concept though. – Crazy Chenz Oct 29 '13 at 02:11

2 Answers2

2

If by "break out", you mean access the Python objects in the calling code, then I'm not sure.

But if by break out, you mean

import subprocess
subprocess.call(['rm', '-rf', '/'])

then definitely yes it can.

Look at pysandbox. Its authors have gone to a lot of work to sandbox eval and friends. I'd go there first if you actually wanted to do this.

Paul Draper
  • 78,542
  • 46
  • 206
  • 285
  • "I am unaware of how you'd grab the scope of the main executable." – Crazy Chenz Oct 29 '13 at 01:58
  • 1
    @PaulDraper, the code can simply raise an exception and catch it, then dig into the traceback object's internals to muck with anything up the call chain. – Tim Peters Oct 29 '13 at 02:05
2

Here's an example. File beast.py:

import inspect
for i, t in enumerate(inspect.stack()):
    if i == 1:
        print 'i in the caller is', t[0].f_globals['i']
        t[0].f_globals['i'] = 666
        t[0].f_globals['j'] = -13

And file xxx.py:

i = 1
execfile("beast.py", {}, {})
print i
print j

Then:

$ python xxx.py
i in the caller is 1
666
-13

It doesn't do any good to prevent importing inspect. The same things can be done by mucking with traceback objects directly. If you want to know how, study inspect.py ;-)

Tim Peters
  • 67,464
  • 13
  • 126
  • 132