46

When upgrading to ruby 3.1, I am seeing the following sort error message when using YAML.load_file some_file_name

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

Other load statements cause similar errors but cite different unspecified classes e.g. OpenStruct. It appears that the latest version of YAML only loads classes from a permitted white list, so it is necessary to use a permitted_class keyword to allow other classes. I have tried

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

but this gives the error

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

how do I fix this?

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Obromios
  • 15,408
  • 15
  • 72
  • 127

6 Answers6

43

Symbol is also not allowed per default. Therefore, you need to add Symbol to the permitted_classes too when loading a file:

hash = YAML.load_file(
  some_file_name, 
  permitted_classes: [Matrix, OpenStruct, Symbol]
)

See the list of default permitted_classes in Psych.

Or, when using in Ruby on Rails, you can configure what classes Rails should permit globally when using YAML files in your config/application.rb:

config.active_record.yaml_column_permitted_classes += [Matrix, OpenStruct, Symbol]

Note that for internal YAML parsing in Ruby on Rails Symbol is already the default for active_record.yaml_column_permitted_classes.

spickermann
  • 100,941
  • 9
  • 101
  • 131
38

The working solution is to add this line to config/application.rb

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

You can do the same with any class name, like

config.active_record.yaml_column_permitted_classes = [Symbol, Hash, Array, ActiveSupport::HashWithIndifferentAccess]
Mohamed Sami
  • 866
  • 10
  • 22
19

Had this on rails 6.1 upgrade. If you have no other choice, maybe this workaround will bring you some time (application.rb):

config.active_record.use_yaml_unsafe_load = true
crazywulf
  • 213
  • 2
  • 5
  • 1
    Full details explaining the change, including other workarounds, are here: https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017 – subelsky Aug 16 '22 at 14:37
  • worked for me...24-09-2022 – Carlos Morales Sep 25 '22 at 03:36
0

When using the YAML.load_file directly, the config.yaml_column_permitted_classes is not used. That is only used, when Rails loads YAML (config files, serialized YAML).

You can:

  • a.) either, pass the list of allowed classes to the YAML.load_file(path, permitted_classes: [..]) like @spickermann has written, or:
  • b.) You can switch to YAML.unsafe_load_file (e.g. for Test cases).
stwienert
  • 3,402
  • 24
  • 28
0

The “safe YAML” loading method does not allow all classes to be deserialized by default. This option allows you to specify classes deemed “safe” in your application. For example, if your application uses Symbol and Time in serialized data, you can add Symbol and Time to the allowed list.

Fixed by adding this to application.rb:

config.active_record.yaml_column_permitted_classes = [Symbol, Date, Time]
maricavor
  • 188
  • 2
  • 10
0

You can change the Rails configuration to use YAML/Psych's unsafe_load (see Mohamed's & crazywulf's answer). I needed to change this config without restarting the Rails app, so I did this:

ActiveRecord.use_yaml_unsafe_load = true

Please mind, this is just a temporary fix for the current process. It will be gone as soon as you restart the server.

Motine
  • 1,638
  • 18
  • 18