1

I'm trying to filter a string before passing it through eval in python. I want to limit it to math functions, but I'm not sure how to strip it with regex. Consider the following:

s = 'math.pi * 8'

I want that to basically translate to 'math.pi*8', stripped of spaces. I also want to strip any letters [A-Za-z] that are not followed by math\..

So if s = 'while(1): print "hello"', I want any executable part of it to be stripped:

s would ideally equal something like ():"" in that scenario (all letters gone, because they were not followed by math\..

Here's the regex I've tried:

(?<!math\.)[A-Za-z\s]+

and the python:

re.sub(r'(?<!math\.)[A-Za-z\s]+', r'', 'math.pi * 8')

But the result is '.p*8', because math. is not followed by math., and i is not followed by math..

How can I strip letters that are not in math and are not followed by math.?

What I ended up doing

I followed @Thomas's answer, but also stripped square brackets, spaces, and underscores from the string, in hopes that no python function can be executed other than through the math module:

s = re.sub(r'(\[.*?\]|\s+|_)', '', s)
s = eval(s, {
    '__builtins__' : None,
    'math' : math
    })
4

1 回答 1

2

正如@Carl 在评论中所说,看看lybniz为更好的事情做了什么。但这还不够!

链接中描述的技术如下:

print eval(raw_input(), {"__builtins__":None}, {'pi':math.pi})

但这并不能阻止类似的事情

([x for x in 1.0.__class__.__base__.__subclasses__()
   if x.__name__ == 'catch_warnings'][0]()
   )._module.__builtins__['__import__']('os').system('echo hi!')

资料来源:Ned Batchelder 关于沙盒的几篇文章,请参阅http://nedbatchelder.com/blog/201302/looking_for_python_3_builtins.html

编辑:指出我们没有方括号或空格,所以:

1.0.__class__.__base__.__subclasses__().__getitem__(i)()._module.__builtins__.get('__import__')('os').system('echo hi')

您只需为 i 尝试很多值。

于 2013-10-10T03:38:22.927 回答