Is this a safe use of eval?

Ryan Kelly ryan at rfk.id.au
Thu Feb 24 10:13:51 CET 2011


On Thu, 2011-02-24 at 10:48 +0200, Frank Millman wrote:
> Hi all
> 
> I know that the use of 'eval' is discouraged because of the dangers of 
> executing untrusted code.
> 
> Here is a variation that seems safe to me, but I could be missing something.
> 
> I have a class, and the class has one or more methods which accept various 
> arguments and return a result.
> 
> I want to accept a method name and arguments in string form, and 'eval' it 
> to get the result.
> 
> Assume I have an instance called my_inst, and a method called 'calc_area', 
> with arguments w and h.
> 
> I then receive my_string  = 'calc_area(100, 200)'.
> 
> >>> result = eval('my_inst.{0}'.format(my_string))
> 
> This will only work if the string contains a valid method name with valid 
> arguments.
> 
> Can anyone see anything wrong with this?

Yes.  A serious problem.

Here's an example of what you describe:


    >>> class MyClass(object):
    ...     def calc_area(self,x,y):
    ...         return 42
    ... 
    >>> inst = MyClass()
    >>>
    >>> def testit(query):
    ...     return eval("inst.{0}".format(query))
    >>>

It works as you expect when used properly:

    >>> testit('calc_area(3,4)')
    42

But actually it allows all sorts of nasty things.  Watch me open an
arbitrary file on your system (assuming you have permission of course).

First find out how to access the "file" builtin:

    >>> testit('__class__.__mro__[-1].__subclasses__().index(file)')
    58

Great, plug that in and we're in business:

    >>> testit('__class__.__mro__[-1].__subclasses__()[58]("/secret/file","w")')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in testit
      File "<string>", line 1, in <module>
    IOError: [Errno 2] No such file or directory: '/secret/file'
    >>>

So please, don't do this!  :-)


   Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
ryan at rfk.id.au        |  http://www.rfk.id.au/ramblings/gpg/ for details

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://mail.python.org/pipermail/python-list/attachments/20110224/68a530f0/attachment.sig>


More information about the Python-list mailing list