我正在开发一个允许用户在我们的系统上运行代码的系统。虽然他们的代码是沙箱,但我仍然想知道他们的代码是否使用某些语句,尤其是导入。这用于快速检查违反平台准则的恶意代码或代码,它不是唯一的检查,因为代码也会被人类检查,但是自动过滤掉最坏的情况会更好
那么在不执行代码的情况下,最好的方法是检查他们的代码是否导入sys
(或sys
的一部分)?我希望有一个更好/更好的方式然后正则表达式搜索该代码。
奖金问题:更复杂的陈述怎么样?例如,从模块foo
调用bar
?
编辑:这不是关于安全性的问题。这是关于在代码中查找某些语句。看我的评论。此用户代码只能在用户沙箱中运行,因此它们可能会破坏自己的沙箱。但是,如果他们的代码被“认证”,它可以在其他用户沙箱中运行,在获得认证之前需要进行检查。如果自动检查可以发现最严重的违规行为,那将会有所帮助。
答案 0 :(得分:3)
我真的不愿意尝试做这种人工沙盒,因为
1024 ** 1024 ** 1024
仍然会咀嚼你的翻译。
甚至是
eval("__vzcbeg__('gvzr').nfpgvzr()")
如果你想要一些安全性,请查看pypy的sandbox,了解运行不受信任的python代码的最安全方法。有一些只有python的模块,如pysandbox,但我个人建议使用pypy沙箱。
答案 1 :(得分:1)
你不能仅仅通过对代码的静态分析来做到这一点,因为它总是可以做一些棘手的事情,例如:
>>> getattr(__builtins__, "__" + chr(105) + "mport__")("sys")
<module 'sys' (built-in)>
正如您所看到的,查看反汇编,代码或ast不会有帮助,因为它甚至包含字符串&#34; import&#34;:
>>> import dis
>>> dis.dis(lambda: getattr(__builtins__, "__" + chr(105) + "mport__")("sys"))
1 0 LOAD_GLOBAL 0 (getattr)
3 LOAD_GLOBAL 1 (__builtins__)
6 LOAD_CONST 1 ('__')
9 LOAD_GLOBAL 2 (chr)
12 LOAD_CONST 2 (105)
15 CALL_FUNCTION 1
18 BINARY_ADD
19 LOAD_CONST 3 ('mport__')
22 BINARY_ADD
23 CALL_FUNCTION 2
26 LOAD_CONST 4 ('sys')
29 CALL_FUNCTION 1
32 RETURN_VALUE
答案 2 :(得分:1)
我认为你根本无法可靠地发现那种东西。请考虑以下事项:
>>> f = None
>>> b = vars()[[f for f in vars() if 'ti' in f][0]]
>>> m = getattr(b, [f for f in dir(b) if 't_' in f][0])
>>> m('x\x9c+\xae,\x06\x00\x02\xc1\x01`'.decode('zip'))
<module 'sys' (built-in)>
答案 3 :(得分:1)
虽然真正的沙子拳击确实非常困难,但是如果它是你试图抓住的 import 声明,请考虑一下:
>>> org_imp = __builtins__.__import__
>>> def imp_hook(*args, **kw):
if args[0] == 'sys':
print 'Gotcha!!'
return None
return org_imp
>>> __builtins__.__import__ = imp_hook
>>> import sys
Gotcha!!
>>> sys
>>> print sys
None
无论import语句本身的复杂程度如何,这项工作都是如此。
注意:不要只打印&amp;返回无,抛出有意义的异常,但你明白了!
答案 4 :(得分:0)
您可以使用ast
python模块来分析Python代码。请参阅我在这里回答一个非常相似的问题:
https://stackoverflow.com/a/8255293/589206
以下是导入语句问题的解决方案:
import ast
import sys
class FunctionNameFinder(ast.NodeVisitor):
def visit_Import(self, node):
print "Importing on line", node.lineno, ":",
for i in node.names: print i.name,
print
with open(sys.argv[1], 'rU') as f:
FunctionNameFinder().visit(ast.parse("".join(f.readlines())))
当然,如果恶意用户花费大量精力来模糊他的代码,这将无济于事,但是,唯一的方法就是使用真正的沙箱。但这首先不是你的问题。
答案 5 :(得分:0)
您要做的是一个常见的场景:您已经通过在沙箱中运行来对代码进行动态分析。除此之外,您还希望使用其他工具进行静态分析,并为您阅读该程序。
这两种方法都有其自身的缺点,并且由于计算的性质,它们都不能保证为您提供各种潜在的方案出错;但是,两者的结合仍然可以在更高的置信度下为您提供大量有用的信息。
在其他流行语言中,例如C / C ++,有一些强大的工具(例如Lint)可以深入分析代码并报告许多潜在问题,包括与安全相关的问题。
不幸的是,Python没有具有高稳健性水平的工具。话虽如此,你仍然可以做很多事情。我认为你最好的选择就是使用PyLint。
PyLint附带了一些代码分析的标准规则,但您可以覆盖这些规则以自定义您自己的代码气味。
例如,如果您只是希望看到正在使用的模块类型,则可以使用imports checker。要处理更复杂的方案,您可以自定义和扩展功能。看看他们的documentation for enhancing PyLint。
看一下tutorial开始: