我希望我的程序用户能够在不破坏程序的情况下在python中定义自定义脚本。我正在看这样的事情:
def call(script):
code = "access modification code" + script
exec(code)
其中"访问修改代码"定义一个范围,使脚本只能访问它实例化的变量。是否可以执行此操作或具有类似功能的内容,例如创建具有自己作用域的新python环境,然后从中接收输出?
感谢您的时间:)
澄清编辑 "我想防止主动攻击和与用户脚本之外的程序变量的意外交互(因此隐藏所有全局变量)。用户脚本很小并以文本形式输入。用户脚本的返回需要立即进行,就好像它是程序本机的一样。"
答案 0 :(得分:1)
在这种情况下,您要阻止两个单独的问题:
对于第一个问题,您需要确保您执行的python代码的来源是用户。您不应接受来自套接字或其他用户可以写入的文件的输入。您需要以某种方式确保正在运行提供输入的程序的用户。 实际解决方案取决于您的操作系统,但如果您将代码存储在文件中,则可能需要考虑设置限制性文件权限。
请勿忽略或淡化此问题,否则您的用户将因您的程序而成为病毒/恶意软件/黑客的受害者。
解决第二个问题的方式取决于程序中预期行为的确切构成。如果您对输出简单的数据结构感到满意,可以在单独的进程中运行用户输入的代码,并以序列化格式(如JSON或YAML)将结果传递给管道。
这是一个非常简单的例子:
#remember to set restrictive file permissions on this file. This is OS-dependent
USER_CODE_FILE="/home/user/user_code_file.py"
#absolute path to python binary (executable)
PYTHON_PATH="/usr/bin/python"
import subprocess
import json
user_code= '''
import json
my_data= {"a":[1,2,3]}
print json.dumps(my_data)
'''
with open(USER_CODE_FILE,"wb") as f:
f.write(user_code)
user_result_str= subprocess.check_output([PYTHON_PATH, USER_CODE_FILE])
user_result= json.loads( user_result_str )
print user_result
这是一个相当简单的解决方案,它有很大的开销。如果您需要在短时间内多次运行用户代码,请不要使用此功能。
最终,此解决方案仅对不熟练的攻击者(用户)有效。一般来说,没有办法保护用户自己的任何用户进程 - 也没有多大意义。
如果您真的想要更多保证,并希望减轻第一个问题,那么您应该以独立(“访客”)用户身份运行该流程。这也是依赖于操作系统的。
最后发出警告:尽最大努力避免exec
和eval
。它们不会保护您的程序或用户免受输入的代码。网上有很多关于此的信息,只需搜索“python secure eval”