On Tue, Nov 07, 2017 at 03:35:58PM +0200, Serhiy Storchaka wrote: > 07.11.17 12:29, אלעזר пише: > >Also, it is unfortunate that `ast.literal_eval` is less accessible than > >`builtins.eval`. Giving it an alias in builtins might make it easier for > >programmers (and less scary - "ast" might sound like I need a PhD to use > >it). > > ast.literal_eval is not so safe as you think. Malicious input can cause > a stack overflow in your program. [1] > > [1] https://bugs.python.org/issue31113
I don't see anything about literal_eval in that bug report. In any case, I think that securing literal_eval is much simpler than securing eval: try: # a thousand character expression ought to be enough for # any legitimate purpose... value = literal_eval(tainted_string[:1000]) # untested except MemoryError: value = None versus, well, there's no obvious or simple way to secure eval. You might get something reasonable with: if '_' in tainted_string: raise ValueError("no underscores allowed!") globalns = {'__builtins__': None} # I think? eval(tainted_string[:1000], globalns, globalns) but even that is probably vulnerable to a clever enough attacker. I tried this on my computer with Python 3.5: # Build a deeply nested dict {'x':{'x':{...}}} as a string s = "{'x':0}" for i in range(1665): s = "{'x':%s}" % s assert len(s) < 10000 d = ast.literal_eval(s) and it failed with MemoryError rather than a segfault, so that's something. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/