用户控制数据的反序列化¶
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
使用任何允许构建任意对象的方法反序列化不受信任的数据很容易被利用,并且在许多情况下允许攻击者执行任意代码。
建议¶
如果可能,请避免反序列化不受信任的数据。如果架构允许,请使用无法表示任意对象的序列化格式。对于支持该功能的库,例如 Ruby 标准库的 JSON
模块,请确保解析器配置为禁用反序列化任意对象。
如果使用 psych
gem 反序列化不受信任的 YAML 文档,请优先使用 safe_load
和 safe_load_file
方法,而不是 load
和 load_file
,因为前者可以安全地处理不受信任的数据。避免将不受信任的数据传递给 load_stream
方法。在 psych
版本 4.0.0 及更高版本中,load
方法可以安全使用。
如果使用 ox
gem 反序列化不受信任的 XML 文档,请不要使用 parse_obj
和 load
,它们使用非默认的 :object 模式。相反,请在默认模式下使用 load
方法,或者更好地显式设置安全模式,例如 :hash。
要安全地使用 plist
gem 反序列化 属性列表 文件,请确保在调用 Plist.parse_xml
时传递 marshal: false
。
示例¶
以下示例在来自 HTTP 请求的数据上调用 Marshal.load
、JSON.load
、YAML.load
、Oj.load
和 Ox.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.parse
和 YAML.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
参考¶
OWASP 漏洞描述:反序列化不受信任的数据。
Ruby 文档:安全反序列化对象的指南。
Ruby 文档:Marshal 库的安全指南。
Ruby 文档:JSON.load 的安全指南。
Ruby 文档:YAML 库的安全指南。
您可以阅读不安全的 yaml load 方法如何导致代码执行:Ruby 2.x-3.x 的通用反序列化工具。
通用弱点枚举:CWE-502。