我如何安全地运行不受信任的python代码?

问题描述 投票:3回答:2

在这种情况下,我的网站上有一些不安全的代码由网站用户生成,无法在我的服务器上运行。

我想为python禁用一些保留字以保护我的运行环境,例如evalexecprint等上。

是否有一种简单的方法(无需更改python解释器,我的python版本是2.7.10)来实现我之前描述的功能?

非常感谢。

python sandbox
2个回答
1
投票

禁用python级别的名称将无济于事,因为有很多解决方法。有关更多信息,请参见thisthis帖子。这是您需要做的:

对于CPython,请使用RestrictedPython定义Python的受限子集。

对于PyPy,请使用sandboxing。它允许您在特殊的环境中运行序列化所有输入/输出的任意python代码,以便您可以在实际运行它们之前检查它并确定允许哪些命令。

由于3.8版本的Python支持audit hooks,因此您可以完全阻止某些操作:

import sys

def audit(event, args):
    if event == 'compile':
        sys.exit('nice try!')

sys.addaudithook(audit)

eval('5')

另外,为了保护主机操作系统,请使用

  • 虚拟化(更安全),例如KVM或VirtualBox

  • 或容器化(轻得多),例如lxddocker

在使用Docker进行容器化的情况下,您可能需要添加AppArmor或SELinux策略,以提高安全性。默认情况下,lxd已随附AppArmor策略。

确保您以尽可能少的特权作为用户运行代码。

为每个用户重建虚拟机/容器。

无论使用哪种解决方案,请不要忘记限制资源使用(RAM,CPU,存储,网络)。如果您选择的虚拟化/容器化解决方案不支持这些限制,请使用cgroups

最后但并非最不重要的一点是,使用超时来防止用户代码永远运行。


0
投票

一种方法是隐藏方法:

def not_available(*args, **kwargs):
    return 'Not allowed'

eval = not_available
exec = not_available
print = not_available

但是,聪明的人总是可以做到这一点:

import builtins
builtins.print('this works!')

因此,[[real解决方案是解析代码,如果有这样的语句,则不允许输入(而不是尝试禁用它们)。

© www.soinside.com 2019 - 2024. All rights reserved.