我写了一个程序,孩子们(12-18岁)可以用它学习用Python编写代码。它的灵感来自一个名为PythonKara(https://www.swisseduc.ch/informatik/karatojava/pythonkara/)的程序。虽然PythonKara是基于Jython的,但我完全用Python、pygame和tkinter编写了我的版本
使用一组给定的命令(如move()、turnlift()、…),用户必须操纵宇宙飞船来完成不同的任务,这些任务(越复杂)也需要Python语法。 该程序有两个窗口。一个窗口显示精灵(pygame窗口),另一个窗口是编辑器(tkinter窗口)
用户输入(self.userInput->;self.userOutput)被发送到pygame窗口的游戏循环,以便使用Python的“exec()”函数执行。为了防止高级用户使用Python模块,例如“os”模块或任何其他可能危害系统的命令,我在执行之前解析用户输入
我的问题是,我的“validateUserCode()”函数是否足以确保安全使用“exec()”函数,还是我必须实施进一步的安全措施
代码说明:
def validateUserCode(self):
unsupported_commands = ['import ','print(', 'with ', '.close(', '.read(', '.readline(', 'open(']
for command in unsupported_commands:
if command in self.userOutput:
raise UnsupportedCommandError(command)
主循环代码(pygame窗口)
try:
user_code = editor.validateUserCode()
exec(user_code, local_variables)
except:
pass
不,这是不安全的,而且永远不会真正安全。请参阅此快速演示:
或者,如果您愿意的话,可以选择更模糊的一种:
另外:您正试图将
'print('
列入黑名单,这仍然使print ("foo")
100%可用,这一事实表明您不应该费心尝试实现这一点以下是我所做的:
exec()
{builtins.__dict__
似乎已经是对builtins.__dict__
的引用,所以在我将代码修改为imp = __builtins__[f"__{''.join(map(chr,(105,109,112,111,114,116)))}__"]
之后,一切都按预期工作,当然它很容易绕过我的弱验证函数李>exec()
的使用李>由于学生们只需要一小部分Python的
builtins
函数,在进行了更多的研究之后,我采用了白名单方法,将__builtins__
设置为空字典,从而禁用了它在exec()
中的使用。所以现在ruohola的代码不再工作了,因为它不可能使用import
。问题是这种方法是否足够(参见第4条)我考虑的另一个解决方案是使用pyinstaller打包文件,并在spec文件中排除os。然后我必须重写代码中使用
os.path
和os.path.join
的部分(如果有意义的话)如果我理解正确-使用
exec()
的主要威胁是可能使用os模块,从而能够访问和删除(重要)文件(即与操作系统相关)。但是它不可能访问其他用户的文件,或者会吗总而言之,我考虑了学校的情况
exec()
是否有意义李>相关问题 更多 >
编程相关推荐