我写了一个主要的python模块,需要加载文件解析器才能工作,最初我只是一个文本解析器模块,但我需要为不同的情况添加更多的解析器.
parser_class1.py
parser_class2.py
parser_class3.py
每个运行实例只需要一个,然后我想通过命令行加载它:
mmain.py -p parser_class1
Run Code Online (Sandbox Code Playgroud)
为此,我编写了这段代码,以便在调用主模块时选择要加载的解析器:
#!/usr/bin/env python
import argparse
aparser = argparse.ArgumentParser()
aparser.add_argument('-p',
action='store',
dest='module',
help='-p module to import')
results = aparser.parse_args()
if not results.module:
aparser.error('Error! no module')
try:
exec("import %s" %(results.module))
print '%s imported done!'%(results.module)
except ImportError, e:
print e
Run Code Online (Sandbox Code Playgroud)
但是,我正在读这种方式很危险,也许没有标准.
那么,这种方法可以吗?或者我必须找到另一种方法来做到这一点?为什么?谢谢,欢迎任何评论.
你实际上只需import在条件块中执行语句:
if x:
import module1a as module1
else:
import module1b as module1
Run Code Online (Sandbox Code Playgroud)
您可以使用此方法以不同方式考虑各种白名单模块导入,但有效的想法是预先编程导入,然后基本上使用GOTO进行正确的导入...如果您确实想让用户导入任何任意参数,那么__import__函数将是要走的路,而不是eval.
更新:
正如@thedox在评论中提到的那样,该as module1部分是用不同底层代码加载类似API的惯用方法.在您打算使用完全不同的API执行完全不同的事情的情况下,这不是要遵循的模式.在这种情况下,更合理的模式是包含与该import语句的特定导入相关的代码:
if ...:
import module1
# do some stuff with module1 ...
else:
import module2
# do some stuff with module2 ...
Run Code Online (Sandbox Code Playgroud)
至于安全性,如果你允许用户造成一些任意代码设置的进口(如自己的模块,也许?),它并不比使用太大的不同eval的用户输入.它本质上是同一个漏洞:用户可以让你的程序执行自己的代码.
根本不认为让用户导入任意模块是一种真正安全的方式.这里的例外情况是,如果他们无法访问文件系统,因此无法创建要导入的新代码,在这种情况下,您基本上会回到白名单案例,并且还可以实施明确的白名单以防止将来 - 如果/在将来的某个时刻用户确实获得文件系统访问权限的漏洞.
| 归档时间: |
|
| 查看次数: |
784 次 |
| 最近记录: |