从库输入构建的不安全 shell 命令¶
ID: rb/shell-command-constructed-from-input
Kind: path-problem
Security severity: 6.3
Severity: error
Precision: high
Tags:
- correctness
- security
- external/cwe/cwe-078
- external/cwe/cwe-088
- external/cwe/cwe-073
Query suites:
- ruby-code-scanning.qls
- ruby-security-extended.qls
- ruby-security-and-quality.qls
使用导出函数的输入动态构建 shell 命令可能会无意中改变 shell 命令的含义。使用导出函数的客户端可能会使用包含 shell 以特殊方式解释的字符的输入,例如引号和空格。这会导致 shell 命令行为不当,甚至允许恶意用户在系统上执行任意命令。
建议¶
如果可能,请避免将 shell 字符串连接到 system(..)
等 API,以避免 shell 解释。
相反,请将 shell 命令的参数作为单独的参数提供给 API,例如 system("echo", arg1, arg2)
。
或者,如果必须动态构建 shell 命令,请添加代码以确保特殊字符不会意外地改变 shell 命令。
示例¶
以下示例显示了从远程 URL 下载文件的动态构建的 shell 命令。
module Utils
def download(path)
system("wget #{path}") # NOT OK
end
end
但是,如果输入包含空格或 shell 以特殊方式解释的其他特殊字符,则 shell 命令将无法按预期工作。
更糟糕的是,客户端可能会传递用户控制的数据,而不知道输入被解释为 shell 命令。这可能允许恶意用户提供输入 http://example.org; cat /etc/passwd
以执行命令 cat /etc/passwd
。
为了避免这种可能造成灾难性的行为,请将导出函数中的输入作为不经过 shell 解释的参数提供。
module Utils
def download(path)
# using an API that doesn't interpret the path as a shell command
system("wget", path) # OK
end
end