升级到Ruby 3.1后,使用YAML.load_file时会导致Psych :: DisallowedClass异常。

51

在升级到 Ruby 3.1 时,当使用 YAML.load_file some_file_name 时,我看到以下排序错误信息

 Psych::DisallowedClass:
   Tried to load unspecified class: Matrix

其他加载语句也会引起类似的错误,但引用不同的未指定类,例如OpenStruct。看起来最新版本的YAML仅从允许的白名单中加载类,因此需要使用permitted_class关键字来允许其他类。我已经尝试过。

hsh = YAML.load_file some_file_name, permitted_classes: [Matrix, OpenStruct]

但是这会导致错误。

 Psych::DisallowedClass:
   Tried to load unspecified class: Symbol

我该如何修复这个问题?

6个回答

48
在Ruby中加载YAML时,默认情况下也不允许使用Symbol。因此,在读取YAML文件时,您需要将Symbol添加到permitted_classes中,以便在您的情况下也能够使用它。
hash = YAML.load_file(
  some_file_name, 
  permitted_classes: [Matrix, OpenStruct, Symbol]
)

查看Psych(Ruby使用的YAML解析器)中默认的permitted_classes列表。
或者,在Ruby on Rails中使用时,您可以在config/application.rb中全局配置您的Ruby on Rails应用程序在读取YAML文件时应允许的类列表。
config.active_record.yaml_column_permitted_classes += [Matrix, OpenStruct, Symbol]

请注意,在Ruby on Rails中进行内部YAML解析时,默认情况下已经使用Symbol作为active_record.yaml_column_permitted_classes的默认值。

40

解决方案是将此行添加到config/application.rb中。

config.active_record.yaml_column_permitted_classes = [ActiveSupport::HashWithIndifferentAccess]

您可以使用任何类名进行相同操作,比如

config.active_record.yaml_column_permitted_classes = [Symbol, Hash, Array, ActiveSupport::HashWithIndifferentAccess]

19

我在进行Rails 6.1升级时遇到了这个问题。如果你别无选择,也许这个解决方法能帮你节省一些时间(在application.rb文件中):

config.active_record.use_yaml_unsafe_load = true

2
完整的更改说明,包括其他解决方法,请参见:https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017 - subelsky
对我有用...2022年9月24日 - Carlos Morales

1

当直接使用YAML.load_file时,config.yaml_column_permitted_classes不会被使用。只有在Rails加载YAML(配置文件,序列化的YAML)时才会使用。

您可以:

  • a.) 象@spickermann所写的那样,将允许的类列表传递给YAML.load_file(path, permitted_classes: [..]),或者:
  • b.) 您可以切换到YAML.unsafe_load_file(例如用于测试案例)。

0

“安全的YAML”加载方法默认情况下不允许反序列化所有类。此选项允许您在应用程序中指定被视为“安全”的类。例如,如果您的应用程序在序列化数据中使用Symbol和Time,则可以将Symbol和Time添加到允许列表中。

通过将以下内容添加到application.rb进行修复:

config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]

1
我尝试过这个方法,无论是在config/application.rb文件中还是在每个环境配置文件中都试过了,但对我来说都没有起作用。 - huertanix

0

您可以更改Rails配置以使用YAML/Psych的unsafe_load(请参见Mohamed和crazywulf的答案)。我需要在不重启Rails应用程序的情况下更改此配置,因此我执行了以下操作:

ActiveRecord.use_yaml_unsafe_load = true

请注意,这只是当前流程的临时修复措施。一旦您重新启动服务器,它将消失。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接