操作系统命令中使用的不受控制的数据¶
ID: cpp/command-line-injection
Kind: path-problem
Security severity: 9.8
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-078
- external/cwe/cwe-088
Query suites:
- cpp-code-scanning.qls
- cpp-security-extended.qls
- cpp-security-and-quality.qls
该代码将用户输入作为对 system
或 popen
的调用的部分传递,而不会转义特殊元素。它使用 sprintf
生成命令行,其中用户提供的数据直接作为格式化参数传递。这使得代码容易受到命令注入攻击。
建议¶
在将用户提供字符串传递给命令 shell 之前,使用库例程转义其中的字符。
示例¶
以下示例以两种方式运行外部命令。第一种方式使用 sprintf
直接从用户提供参数构建命令。因此,它容易受到命令注入。第二种方式在将用户提供值嵌入到命令之前对其进行引用;假设 encodeShellString
实用程序正确,则此代码应能防止命令注入。
int main(int argc, char** argv) {
char *userName = argv[2];
{
// BAD: a string from the user is injected directly into
// a command line.
char command1[1000] = {0};
sprintf(command1, "userinfo -v \"%s\"", userName);
system(command1);
}
{
// GOOD: the user string is encoded by a library routine.
char userNameQuoted[1000] = {0};
encodeShellString(userNameQuoted, 1000, userName);
char command2[1000] = {0};
sprintf(command2, "userinfo -v %s", userNameQuoted);
system(command2);
}
}
参考¶
CERT C 编码标准:STR02-C. 净化传递给复杂子系统的数据。
OWASP:命令注入。
常见弱点枚举:CWE-78。
常见弱点枚举:CWE-88。