audited
audited copied to clipboard
Error after upgrading to Rails 6.0.5.1: Psych::DisallowedClass: Tried to load unspecified class: ActiveSupport::TimeWithZone
Hello, I upgraded a Rails app from 6.0.5 to 6.0.5.1 which was released yesterday, and saw this error when saving an audited record:
Psych::DisallowedClass: Tried to load unspecified class: ActiveSupport::TimeZone
It happens when using YAML to deserialize an audit record with a column of ActiveSupport::TimeWithZone
type:
From: /Users/kevin/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/audited-5.0.2/lib/audited/audit.rb:23 Audited::YAMLIfTextColumnType.load:
20: def load(obj)
21: if text_column?
22: binding.pry
=> 23: ActiveRecord::Coders::YAMLColumn.new(Object).load(obj)
24: else
25: obj
26: end
27: end
pry(Audited::YAMLIfTextColumnType)> puts obj
---
first_name: Test
last_name: Test
email: [email protected]
phone: "+15555555555"
[…]
confirmation_sent_at: !ruby/object:ActiveSupport::TimeWithZone
utc: &1 2022-07-13 07:42:50.642612000 Z
zone: !ruby/object:ActiveSupport::TimeZone
name: Etc/UTC
time: *1
[…]
After investigating, it's a direct result from the security patch introduced in Rails 7.0.3.1, 6.1.6.1, 6.0.5.1 and 5.2.8.1 and I was able to configure the application to permit some classes. In my case:
# in config/application.rb
# List of classes deemed safe to load by YAML, and required by the Audited
# gem when deserialized audit records.
# As of Rails 6.0.5.1, YAML safe-loading method does not allow all classes
# to be deserialized by default: https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017
config.active_record.yaml_column_permitted_classes = [
ActiveSupport::HashWithIndifferentAccess,
ActiveSupport::TimeWithZone,
ActiveSupport::TimeZone,
Date,
Time
]
Hope this is useful to other Audited users! Perhaps Audited could come with this config out of the box, or including some guidance in the README?
FYI got the same with
Psych::DisallowedClass: Tried to load unspecified class: ActiveSupport::HashWithIndifferentAccess
@grosser Ah yes, I saw the same in my app after opening the issue above. Updating the issue to make it easier for other Audited users to copy/paste a solution.
I created a script that can help to figure what actually needs to be whitelisted.
See this issue for some discussion and (personally untested) examples of migrating from YAML to JSON
Pretty much same issue when upgrading to Rails 7.0.3.1:
Psych::DisallowedClass: Tried to load unspecified class: ActiveSupport::TimeWithZone
@vrinek this is already mentioned in the initial message of this thread.
The fast, unsafe and wrong way:
config.active_record.use_yaml_unsafe_load = ture
The correct way is to eighter somehow migrate to the JSON store or whitelist ruby that being serialized classes:
My case:
config.active_record.yaml_column_permitted_classes =
%w[String Integer NilClass Float Time Date FalseClass Hash Array DateTime TrueClass BigDecimal
ActiveSupport::TimeWithZone ActiveSupport::TimeZone ActiveSupport::HashWithIndifferentAccess]
To find what needs to be whitelisted in your case you can try to use this script:
https://gist.github.com/crawler/47a1e66ee2c2ea37f56f9c0c2aac071a
I do worry that we can't necessarily know what classes may end up in the audit log later on, so no matter how thorough @crawler's script is, it'll only need a new edge case to come along and potentially cause an exception.
It's a good thing this gem defaults to JSON now, so it's only existing users who will need to figure out a safe migration path.
@barrywoolgar sure, this is a better way.
I think it is possible to stay with the YAML because you should know what types are present in the schema of the models that are under audit. But it looks like a large surface for the making mistake out of nothing.
@crawler apologies for not reading the first post thoroughly, and thanks for pointing it out as a possible course of action.
@barrywoolgar "will need to figure out a safe migration path" :sweat_smile:. Yeah, that's gonna take a while to be prioritized. In the meanwhile if anyone has gone through this already, I would love to learn from their experiences.
For now, my migration references include only this:
- https://github.com/collectiveidea/audited/issues/216#issuecomment-215376047
Should we consider adding a config option similar to active record's but scoped only to audited? In our codebase the only library preventing the upgrade is audited
. We don't need to specify the permitted classes array for anything else, so it seems a little overkill to do it for the whole app.
I'd also prefer a migration to JSON. However there doesn't seem to be a clear path yet besides removing the whole audited history.
[deleted my issue] Operator error, carry on, nothing to see with my particular issue.
lets move to json
@crawler is this list all complete?
config.active_record.yaml_column_permitted_classes =
%w[String Integer NilClass Float Time Date FalseClass Hash Array DateTime TrueClass BigDecimal
ActiveSupport::TimeWithZone ActiveSupport::TimeZone ActiveSupport::HashWithIndifferentAccess]
@laptopmutia for two my apps where i used this list.