[Tutor] Re: Suggestions for cleaner code [a safer alternative to input()]

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Wed Jul 9 14:48:01 2003


On Wed, 9 Jul 2003, Jeff Shannon wrote:

> Magnus Lycke wrote:
>
> > At 18:02 2003-07-08 -0700, Jeff Shannon wrote:
> >
> >> Even worse, someone could easily type something like 'import os;
> >> os.system("rm -s /")' -- this *will* import the os module and spawn a
> >> shell that will attempt to delete every file on your system.
> >
> >
> > No it won't. You can only evaluate expressions, not arbitrary
> > statements. But the second part 'os.system("rm -s /")' is certainly
> > possible, so if the program has already imported the os module, you
> > are definitely in danger.
>
>
> Ah, right, my mistake -- input() uses eval() internally, and eval() can
> only handle expressions, not statements.  So the malicious possibilities
> aren't *quite* as open as I had suggested, though they are still
> definitely there, as are the possibilities for unintentional problems.


Hi Jeff,


No, you were right the first time.  *grin*


input(), as it stands, is very powerful.  Because of its power, it's not
usually a good idea to use it for casual user input.  There is a way to
make it slightly less dangerous:


###
>>> def input():
...     return eval(raw_input(), {'__builtins__': None})
...
>>> input()
3*4
12
>>> input()
__import__('os')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in input
  File "<string>", line 0, in ?
NameError: name '__import__' is not defined
###



This modified version of input() still allows for arithmetic expressions,
but we prevent the user from calling any of the builtins.  It probably
still has weaknesses, but it's at least a little safer than the standard
input() function.



Hope this helps!