eval() == evil? --- How to use it safely?

Matimus mccredie at gmail.com
Thu Aug 28 19:56:49 EDT 2008


On Aug 28, 3:09 pm, "Guilherme Polo" <ggp... at gmail.com> wrote:
> On Thu, Aug 28, 2008 at 6:51 PM, Fett <FettMan... at gmail.com> wrote:
> > I am creating a program that requires some data that must be kept up
> > to date. What I plan is to put this data up on a web-site then have
> > the program periodically pull the data off the web-site.
>
> > My problem is that when I pull the data (currently stored as a
> > dictionary on the site) off the site, it is a string, I can use eval()
> > to make that string into a dictionary, and everything is great.
> > However, this means that I am using eval() on some string on a web-
> > site, which seems pretty un-safe.
>
> > I read that by using eval(code,{"__builtins__":None},{}) I can prevent
> > them from using pretty much anything, and my nested dictionary of
> > strings is still allowable. What I want to know is:
>
> > What are the dangers of eval?
> > - I originally was using exec() but switched to eval() because I
> > didn't want some hacker to be able to delete/steal files off my
> > clients computers. I assume this is not an issue with eval(), since
> > eval wont execute commands.
> > - What exactly can someone do by modifying my code string in a command
> > like: thing = eval(code{"__builtins__":None},{}), anything other than
> > assign their own values to the object thing?
>
> By "disabling" __builtins__ you indeed cut some obvious tricks, but
> someone still could send you a string like "10 ** 10 ** 10".
>
> > --
> >http://mail.python.org/mailman/listinfo/python-list
>
> --
> -- Guilherme H. Polo Goncalves

Or, they could pass in something like this:

(t for t in 42 .__class__.__base__.__subclasses__() if t.__name__ ==
'LibraryLoader').next()((t for t in
__class__.__base__.__subclasses__() if t.__name__ ==
'CDLL').next()).msvcrt.system("SOMETHING MALICIOUS")

Which can be used to execute pretty much anything on a Windows system
using a "safe" eval. This same exploit exists in some form on *nix.
The above assumes that ctypes has been loaded. It can be modified to
call code in other modules that have been loaded though as well.

Matt



More information about the Python-list mailing list