Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Is this a safe use of eval?

Reply
Thread Tools

Is this a safe use of eval?

 
 
Frank Millman
Guest
Posts: n/a
 
      02-24-2011
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?

Thanks

Frank Millman


 
Reply With Quote
 
 
 
 
Paul Rubin
Guest
Posts: n/a
 
      02-24-2011
"Frank Millman" <(E-Mail Removed)> writes:
> 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?


Um, yes. What are valid arguments? Are you going to eval them?

If they can only be literals, maybe you could use something like

from ast import literal_eval
method_name = 'calc_area'
args = literal_eval('(100,200)')
result = getattr(my_inst, method_name)(*args)

but even that is risky in a hostile data environment.
 
Reply With Quote
 
 
 
 
Peter Otten
Guest
Posts: n/a
 
      02-24-2011
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?


How do you prevent that a malicious source sends you

my_string = 'calc_area(__import__("os").system("rm important_file") or 100,
200)'

instead?

 
Reply With Quote
 
Web Dreamer
Guest
Posts: n/a
 
      02-24-2011
Frank Millman a écrit ce jeudi 24 février 2011 09:48 dans
<(E-Mail Removed)> :

> 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.


I'd do it that way:

>>> class My_Class(object):

.... def calc_area(self, a, b):
.... return a*b
....
>>> my_inst = My_Class()
>>> my_string = 'calc_area(100, 200)'
>>> my_func_and_args = my_string.split('(')
>>> my_func = my_func_and_args.pop(0)
>>> my_args = my_func_and_args[0].strip(')')
>>> my_args = my_args.split(',')
>>> my_args = [int(arg) for arg in my_args]
>>> if hasattr(my_inst, my_func):

.... getattr(my_inst,my_func)(*my_args)
....
20000


And no eval is ever performed.

--
Web Dreamer

 
Reply With Quote
 
Nobody
Guest
Posts: n/a
 
      02-25-2011
On Thu, 24 Feb 2011 15:24:51 +0200, Frank Millman wrote:

> Thanks, Christian. I had a look at that recipe, but I must say that Paul's
> suggestion is much simpler -
>
> from ast import literal_eval
> method_name = 'calc_area'
> args = literal_eval('(100,200)')
> result = getattr(my_inst, method_name)(*args)
>
> In my case the arguments are all strings or integers, so it looks as if this
> approach should be safe. Do you see any problem with it?


Only that you may need a fairly recent version of the ast module; the
first attempt at literal_eval was a bit too ... literal, e.g. it couldn't
handle negative numbers (Python doesn't have negative integer literals;
evaluating "-10" applies the negation operator to the integer 10).


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
os.ChDir() not thread-safe; was : Is tempfile.mkdtemp() thread-safe? Gabriel Rossetti Python 0 08-29-2008 08:30 AM
Safe Mode (?) - It is meant to be normal mode but looks like safe mode English Patient Computer Support 3 10-03-2004 11:10 PM
Re: Those cute little "WORK-SAFE" / "NOT WORK-SAFE" tags that people put in the Subject headers of their posts... Soapy Digital Photography 1 08-16-2004 12:07 PM
Re: Those cute little "WORK-SAFE" / "NOT WORK-SAFE" tags that people put in the Subject headers of their posts... Soapy Digital Photography 1 08-16-2004 06:24 AM
$SAFE = 5 and Safe Ruby Misleading? kirindave@lensmen.net Ruby 1 08-11-2003 11:35 PM



Advertisments