CodeQL 文档

使用 Kernel.openIO.read 或类似接收器处理用户控制的输入

ID: rb/kernel-open
Kind: path-problem
Security severity: 9.8
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

点击查看 CodeQL 仓库中的查询

如果 Kernel.open 收到的文件名以 | 字符开头,它将把剩余的字符串作为 shell 命令执行。如果恶意用户可以控制文件名,他们可以执行任意代码。同样的漏洞也适用于 IO.readIO.writeIO.binreadIO.binwriteIO.foreachIO.readlinesURI.open

建议

使用 File.open 而不是 Kernel.open,因为前者没有此漏洞。同样,使用 File 类中的方法,而不是 IO 类中的方法,例如 File.read 而不是 IO.read

不要使用 URI.open,而是使用 URI(..).open 或 HTTP 客户端。

示例

以下示例显示了对用户提供的文件路径调用 Kernel.open 的代码。

require "open-uri"

class UsersController < ActionController::Base
  def create
    filename = params[:filename]
    open(filename) # BAD

    web_page = params[:web_page]
    URI.open(web_page) # BAD - calls `Kernel.open` internally
  end
end

相反,应该使用 File.open,如以下示例所示。

class UsersController < ActionController::Base
  def create
    filename = params[:filename]
    File.open(filename)

    web_page = params[:web_page]
    Net::HTTP.get(URI.parse(web_page))
  end
end

参考资料

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