On Wed, 6 Apr 2016 03:48 am, Chris Angelico wrote: > On Wed, Apr 6, 2016 at 3:26 AM, Jon Ribbens > <jon+use...@unequivocal.co.uk> wrote: >> The received wisdom is that restricted code execution in Python is >> an insolubly hard problem, but it looks a bit like my 7-line example >> above disproves this theory,
Jon's 7-line example doesn't come even close to providing restricted code execution in Python. What it provides is a restricted subset of expression evaluation, which is *much* easier. It's barely more powerful than the ast.safe_eval function. That doesn't make it useless, but it does mean that it's not solving the problem of "restricted code execution". [Jon again] >> provided you choose carefully what you >> provide in your restricted __builtins__ - but people who knows more >> than me about Python seem to have thought about this problem for >> longer than I have and come up with the opposite conclusion so I'm >> curious what I'm missing. You're missing that they're trying to allow enough Python functionality to run useful scripts (not just evaluate a few arithmetic expressions), but without allowing the script to break out of the restricted environment and do things which aren't permitted. For example, check out Tav's admirable work some years ago on trying to allow Python code to read but not write files: http://tav.espians.com/a-challenge-to-break-python-security.html and followups to that post here: http://tav.espians.com/paving-the-way-to-securing-the-python-interpreter.html http://tav.espians.com/update-on-securing-the-python-interpreter.html You should also read Guido's comments on capabilities: http://neopythonic.blogspot.com.au/2009/03/capabilities-for-python.html As Zooko says, Guido's "best argument is that reducing usability (in terms of forbidding language features, especially module import) and reducing the usefulness of extant library code" would make the resulting interpreter too feeble to be useful. Look at what you've done: you've restricted the entire world of Python down to, effectively, a calculator and a few string methods. That's not to say that a calculator and a few string methods won't be useful to someone, but the next Javascript it is not... [Chris] > No, it doesn't disprove anything. All you've shown is "here's a piece > of code that hasn't yet been compromised". :) What you're missing is a > demonstrated exploit against your code. I can't provide one, but it's > entirely possible that one will be found. > > Your code is a *lot* safer for using 'eval' rather than 'exec'. > Otherwise, you'd be easily exploited using exceptions, which carry a > ton of info. But even so, I would not bet money (much less the > security of my systems) on this being safe. I think Jon is on the right approach here for restricting evaluation of evaluation, which is a nicely constrained and small subset of Python. He's not allowing unrestricted arbitrary code execution: he has a very restricted (too restricted -- what the hell can you do with just int, str and len?) whitelist of functions that are allowed, and the significant restriction that dunder names aren't allowed. This makes his function a tiny DSL for calculators and equivalent. I think that, if it checks out, it would make a good addition to the standard library. All the obvious, and even not-so-obvious, attack tools are gone: eval, exec, getattr, type, __import__. Because you're not supporting Python 2, the various func.func_* attack surfaces are all gone. Since you can't access dunders directly, and the obvious indirect methods like eval and getattr aren't available, I don't think that any of the usual attacks will work. Keep in mind that Jon's burden is easier: he doesn't need to worry about the caller's environment, only his own environment. So long as the attacker can't inject code into his "safe eval" code, the attacker can monkey-patch their own built-ins and it simply doesn't matter. (If the attacker can monkey-patch Jon's code, they can do anything they like.) I think this approach is promising enough that Jon should take it to a few other places for comments, to try to get more eyeballs. Stackoverflow and Reddit's /r/python, perhaps. Please do followup here with any results, positive or negative. -- Steven -- https://mail.python.org/mailman/listinfo/python-list