该问题与本期中描述的 Ruby 3.1 / Psych 4.x 不兼容有关:https://bugs.ruby-lang.org/issues/17866 https://bugs.ruby-lang.org/issues/17866
Ruby 3.0 附带 Psych 3,而 Ruby 3.1 附带 Psych 4,它有一个重大的突破性变化(差异 3.3.2 → 4.0.0 https://my.diffend.io/gems/psych/3.3.2/4.0.0).
- 新的 YAML 加载方法 (Psych 4) 不会加载别名,除非它们获得
aliases: true
争论。
- 旧的 YAML 加载方法(Psych 3)不支持
aliases
关键词。
此时,似乎任何人、任何地方想要以 Ruby 3.1 之前的方式加载 YAML,都需要执行以下操作:
begin
YAML.load(source, aliases: true, **options)
rescue ArgumentError
YAML.load(source, **options)
end
由 Rails 团队修补 https://github.com/rails/rails/commit/179d0a1f474ada02e0030ac3bd062fc653765dbe.
对于您的情况,我怀疑您需要先查看与您的主要版本首选项匹配的 Rails 版本是否包含此补丁,然后才能升级到 Ruby 3.1。
就我个人而言,只要我能控制加载 YAML 的代码,我就会添加如下扩展:
module YAML
def self.properly_load_file(path)
YAML.load_file path, aliases: true
rescue ArgumentError
YAML.load_file path
end
end
或者,如果我想完全恢复 Psych 4 中所做的更改,我会将其添加到我的代码中:
module YAML
class << self
alias_method :load, :unsafe_load if YAML.respond_to? :unsafe_load
end
end
这样做的好处是可以恢复YAML::load
, and YAML::load_file
(使用它)恢复了最初的辉煌,并解决了所有 Ruby 版本中的所有问题,包括您无法控制的库。
最后,正如我在评论中提到的,如果您更喜欢微创权宜之计,您也许可以将 Psych 固定在< 4
在你的 Gemfile 中:
gem 'psych', '< 4'
Rails 用户注意事项 (>= 7.0.3.1)
ActiveRecord 7.0.3.1更改了内部通话 https://github.com/rails/rails/commit/611990f1a6c137c2d56b1ba06b27e5d2434dcd6a现在它调用safe_load
直接地。如果您在 Rails 测试期间看到 Psych 相关错误,您可能会受到此更改的影响。
要解决此问题,您可以将其添加到新的或现有的初始值设定项中:
# config/initializers/activerecord_yaml.rb
ActiveRecord.use_yaml_unsafe_load = true
您还可以使用ActiveRecord.yaml_column_permitted_classes
配置允许的类。
更多信息在这个帖子 https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017.