CodeQL 文档

用户控制数据的反序列化

ID: rb/unsafe-deserialization
Kind: path-problem
Security severity: 9.8
Severity: warning
Precision: high
Tags:
   - security
   - external/cwe/cwe-502
Query suites:
   - ruby-code-scanning.qls
   - ruby-security-extended.qls
   - ruby-security-and-quality.qls

单击查看 CodeQL 存储库中的查询

使用任何允许构建任意对象的方法反序列化不受信任的数据很容易被利用,并且在许多情况下允许攻击者执行任意代码。

建议

如果可能,请避免反序列化不受信任的数据。如果架构允许,请使用无法表示任意对象的序列化格式。对于支持该功能的库,例如 Ruby 标准库的 JSON 模块,请确保解析器配置为禁用反序列化任意对象。

如果使用 psych gem 反序列化不受信任的 YAML 文档,请优先使用 safe_loadsafe_load_file 方法,而不是 loadload_file,因为前者可以安全地处理不受信任的数据。避免将不受信任的数据传递给 load_stream 方法。在 psych 版本 4.0.0 及更高版本中,load 方法可以安全使用。

如果使用 ox gem 反序列化不受信任的 XML 文档,请不要使用 parse_objload,它们使用非默认的 :object 模式。相反,请在默认模式下使用 load 方法,或者更好地显式设置安全模式,例如 :hash。

要安全地使用 plist gem 反序列化 属性列表 文件,请确保在调用 Plist.parse_xml 时传递 marshal: false

示例

以下示例在来自 HTTP 请求的数据上调用 Marshal.loadJSON.loadYAML.loadOj.loadOx.parse_obj 方法。由于这些方法能够反序列化为任意对象,因此这本身是不安全的。

require 'json'
require 'yaml'
require 'oj'

class UserController < ActionController::Base
  def marshal_example
    data = Base64.decode64 params[:data]
    object = Marshal.load data
    # ...
  end

  def json_example
    object = JSON.load params[:json]
    # ...
  end

  def yaml_example
    object = YAML.load params[:yaml]
    # ...
  end

  def oj_example
    object = Oj.load params[:json]
    # ...
  end

  def ox_example
    object = Ox.parse_obj params[:xml]
    # ...
  end
end

相反,使用 JSON.parseYAML.safe_load,如以下示例所示,消除了此漏洞。同样,使用除 :object 之外的任何模式调用 Oj.load 是安全的,调用 Oj.safe_load 也是安全的。请注意,没有安全的方法可以使用 Marshal 反序列化不受信任的数据。

require 'json'

class UserController < ActionController::Base
  def safe_json_example
    object = JSON.parse params[:json]
    # ...
  end

  def safe_yaml_example
    object = YAML.safe_load params[:yaml]
    # ...
  end

  def safe_oj_example
    object = Oj.load params[:yaml], { mode: :strict }
    # or
    object = Oj.safe_load params[:yaml]
    # ...
  end
end

参考

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