CodeQL 文档

从环境变量构建的 Shell 命令

ID: js/shell-command-injection-from-environment
Kind: path-problem
Security severity: 6.3
Severity: warning
Precision: high
Tags:
   - correctness
   - security
   - external/cwe/cwe-078
   - external/cwe/cwe-088
Query suites:
   - javascript-code-scanning.qls
   - javascript-security-extended.qls
   - javascript-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

使用来自本地环境(如文件路径)的值动态构造 Shell 命令,可能会无意中改变 Shell 命令的含义。这种改变可能发生在环境值包含 Shell 以特殊方式解释的字符时,例如引号和空格。这会导致 Shell 命令行为异常,甚至允许恶意用户在系统上执行任意命令。

建议

如果可能,请使用硬编码的字符串文字来指定要运行的 Shell 命令,并将动态参数分别提供给 Shell 命令,以避免 Shell 解释。

或者,如果必须动态构造 Shell 命令,则添加代码以确保环境值中的特殊字符不会意外地更改 Shell 命令。

示例

以下示例显示了一个动态构建的 Shell 命令,该命令递归地删除位于当前执行的 JavaScript 文件旁边的临时目录。这些实用程序通常存在于自定义构建脚本中。

var cp = require("child_process"),
  path = require("path");
function cleanupTemp() {
  let cmd = "rm -rf " + path.join(__dirname, "temp");
  cp.execSync(cmd); // BAD
}

但是,如果脚本目录的绝对路径包含空格,则 Shell 命令将无法按预期工作。在这种情况下,Shell 命令会将绝对路径解释为多个路径,而不是单个路径。

例如,如果临时目录的绝对路径为 /home/username/important project/temp,则 Shell 命令将递归地删除 /home/username/importantproject/temp,其中后者相对于 JavaScript 进程的工作目录进行解析。

更糟糕的是,虽然可能性较小,但恶意用户可以提供路径 /home/username/; cat /etc/passwd #/important project/temp 以执行命令 cat /etc/passwd

为了避免这种潜在的灾难性行为,请将目录作为参数提供,该参数不会被 Shell 解释

var cp = require("child_process"),
  path = require("path");
function cleanupTemp() {
  let cmd = "rm",
    args = ["-rf", path.join(__dirname, "temp")];
  cp.execFileSync(cmd, args); // GOOD
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私