Last active
November 21, 2022 14:41
-
-
Save chriscz/d8e073a4d17df9e25ed2f9d6d5b73227 to your computer and use it in GitHub Desktop.
After the Rails 5.2.8.1 security release it's required to specify which classes are permitted for deserialization by YAML. However, when it's a high effort task to discover, it's easier to run production in "unsafe" mode for some time and collect which classes are being loaded.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Place under initializers/yaml_autoloader.rb | |
class PsychLoaderPatch | |
include Singleton | |
def initialize | |
logfile = File.open(Rails.root.join("log/yaml_disallowed_classes.log").to_s, "a") | |
logfile.sync = true | |
@logger = Logger.new(logfile) | |
@seen_classes = Set.new | |
@seen_classes_mutex = Mutex.new | |
end | |
def resolve_class(klass_name, &super_block) | |
if klass_name && seen_class?(klass_name) | |
klass_name.safe_constantize | |
else | |
begin | |
super_block.call | |
rescue Psych::DisallowedClass | |
disallowed_class(klass_name) | |
end | |
end | |
end | |
private | |
def seen_class?(klass_name) | |
@seen_classes.include?(klass_name) | |
end | |
def seen_class(klass_name) | |
@seen_classes_mutex.synchronize do | |
@seen_classes << klass_name | |
end | |
end | |
def disallowed_class(klass_name) | |
@logger.info(klass_name) | |
seen_class(klass_name) | |
klass_name.safe_constantize | |
end | |
def self.patch! | |
Psych::Visitors::ToRuby.prepend Module.new { | |
def resolve_class(klass_name) | |
::PsychLoaderPatch.instance.resolve_class(klass_name) { super } | |
end | |
} | |
Psych::ClassLoader::Restricted.prepend Module.new { | |
def find(klass_name) | |
::PsychLoaderPatch.instance.resolve_class(klass_name) { super } | |
end | |
} | |
end | |
end | |
PsychLoaderPatch.patch! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment