代码注入¶
ID: py/code-injection
Kind: path-problem
Security severity: 9.3
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-094
- external/cwe/cwe-095
- external/cwe/cwe-116
Query suites:
- python-code-scanning.qls
- python-security-extended.qls
- python-security-and-quality.qls
在没有适当清理输入的情况下,直接将用户输入(例如,HTTP 请求参数)评估为代码,会允许攻击者执行任意代码。当用户输入传递给将用户输入解释为要评估的表达式的代码时,就会发生这种情况,例如 eval
或 exec
。
建议¶
避免在任何可能被动态评估的表达式中包含用户输入。如果必须包含用户输入,请在包含之前使用特定于上下文的转义。对于将要进行的评估类型,使用正确的转义至关重要。
示例¶
以下示例展示了两个函数从请求中设置名称。第一个函数使用 exec
来执行 setname
函数。这是危险的,因为它可以允许恶意用户在服务器上执行任意代码。例如,用户可以提供 "' + subprocess.call('rm -rf') + '"
这样的值来破坏服务器的文件系统。第二个函数直接调用 setname
函数,因此是安全的。
urlpatterns = [
# Route to code_execution
url(r'^code-ex1$', code_execution_bad, name='code-execution-bad'),
url(r'^code-ex2$', code_execution_good, name='code-execution-good')
]
def code_execution(request):
if request.method == 'POST':
first_name = base64.decodestring(request.POST.get('first_name', ''))
#BAD -- Allow user to define code to be run.
exec("setname('%s')" % first_name)
def code_execution(request):
if request.method == 'POST':
first_name = base64.decodestring(request.POST.get('first_name', ''))
#GOOD --Call code directly
setname(first_name)