Need some quick help here...

Oren Tirosh oren-py-l at hishome.net
Mon Jun 16 12:02:55 CEST 2003


On Sun, Jun 15, 2003 at 09:53:24PM -0600, Zac Jensen wrote:
> I have a bit of an issue in something I'm designing.
> 
> It's a security issue.
> 
> Here's what happens at the point of concern.
> 
> Arbitrary code is accepted to be run through an eval statement that looks like
> 
> eval(a_repr, {'__builtins__':None})
> 
> Anything could be in a_repr but, in the code that uses the return value of 
> eval, it will simply raise an exception if it's not a tuple that is returned.
> 
> Also, the string passed to eval will never include a real newline character, 
> \r and \n are automatically .replace()'d before eval() is called...
> 
> I'm looking for any example that could still cause problems, and optionaly a 
> suggested solution within the bounds of the problem.

Evaluation of this expression, for example, will not finish in a billion 
years:

[0 for a in range(999999) for b in range(999999) for c in range(999999)
for d in range(999999) if 0]

List and string multiplication can result in excessive memory allocation
that will overload the machine's VM and slow everything down to a crawl.

There are many other ways for creative mischief with eval. For example, 
here's how an expression can get a file without access to builtins:

[x for x in ''.__class__.__bases__[0].__subclasses__() 
 if x.__name__ == 'file'][0]

Using this to fill the disk is left as an exercise to the reader.

You can add further preprocessing to the string to prevent these tricks 
but there will be others. By the time you are done you will find that 
you have worked much harder than just avoiding eval() altogether and 
implementing the required functionality some other way.

If you want security, never exec() or eval() untrusted data.

    Oren






More information about the Python-list mailing list