Is this a safe use of eval?

F

Frank Millman

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

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
 
P

Paul Rubin

Frank Millman said:
I then receive my_string = 'calc_area(100, 200)'.
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.
 
P

Peter Otten

Frank said:
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)'.


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?
 
W

Web Dreamer

Frank Millman a écrit ce jeudi 24 février 2011 09:48 dans
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)'.


This will only work if the string contains a valid method name with valid
arguments.

I'd do it that way:
.... 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.
 
N

Nobody

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top