Skip to content

Instantly share code, notes, and snippets.

@rsierra
Last active December 13, 2015 16:49
Show Gist options
  • Save rsierra/4943505 to your computer and use it in GitHub Desktop.
Save rsierra/4943505 to your computer and use it in GitHub Desktop.
Rails <= 2.3 patch for CVE-2013-0269, CVE-2013-0276 and CVE-2013-0277 vulnerabilities

Rails <= 2.3 patch for CVE-2013-0269, CVE-2013-0276 and CVE-2013-0277 vulnerabilities

Extracted from official patchs.

  • Add files in '/config/initializers' directory.

To test the JSON parser (CVE-2013-0269), try to parse a malicious json:

  • In console, before patch:
>> JSON.parse "{\"json_class\":\"JSON::GenericObject\",\"foo\":\"bar\"}"
=> #<JSON::GenericObject foo="bar">
or
=> ArgumentError: undefined class/module JSON::GenericObject
  • After patch:
>> JSON.parse "{\"json_class\":\"JSON::GenericObject\",\"foo\":\"bar\"}"
=> {"json_class"=>"JSON::GenericObject", "foo"=>"bar"}
# From 79fa7f352bae842017c885101a556875600fb468 Mon Sep 17 00:00:00 2001
# From: Florian Frank <[email protected]>
# Date: Mon, 4 Feb 2013 23:28:30 +0100
# Subject: [PATCH] Security fix create_additons problem
# Drop it at your_app/config/initializers/
# Remember to pass your tests/specs
module JSON
class << self
alias :old_parse :parse
def parse(json, args = {})
args[:create_additions] = false
old_parse(json, args)
end
end
end
# From 9a48f4cf329f66682c34c86822d625d63dbb6919 Mon Sep 17 00:00:00 2001
# From: Aaron Patterson <[email protected]>
# Date: Sat, 9 Feb 2013 16:31:04 -0800
# Subject: [PATCH] fixing attr_protected CVE-2013-0276
# Drop it at your_app/config/initializers/
# Remember to pass your tests/specs
module ActiveRecord
module AttributeMethods
module ClassMethods
private
def rebuild_attribute_method_regexp
suffixes = attribute_method_suffixes.map { |s| Regexp.escape(s) }
@@attribute_method_regexp = /(#{suffixes.join('|')})\z/.freeze
end
end
end
end
module ActiveRecord
class Base
private
def remove_attributes_protected_from_mass_assignment(attributes)
safe_attributes =
if self.class.accessible_attributes.nil? && self.class.protected_attributes.nil?
attributes.reject { |key, value| attributes_protected_by_default.include?(key.gsub(/\(.+/m, "")) }
elsif self.class.protected_attributes.nil?
attributes.reject { |key, value| !self.class.accessible_attributes.include?(key.gsub(/\(.+/m, "")) || attributes_protected_by_default.include?(key.gsub(/\(.+/m, "")) }
elsif self.class.accessible_attributes.nil?
attributes.reject { |key, value| self.class.protected_attributes.include?(key.gsub(/\(.+/m,"")) || attributes_protected_by_default.include?(key.gsub(/\(.+/m, "")) }
else
raise "Declare either attr_protected or attr_accessible for #{self.class}, but not both."
end
removed_attributes = attributes.keys - safe_attributes.keys
if removed_attributes.any?
# This method is only present in rails > 2.2.1
# log_protected_attribute_removal(removed_attributes)
# We use logger isntead
logger.debug "WARNING: Can't mass-assign these protected attributes: #{removed_attributes.join(', ')}"
end
safe_attributes
end
end
end
# From d4a53b2e02106c6734bbfea2a0e209febd5f36bd Mon Sep 17 00:00:00 2001
# From: Tobias Kraze <[email protected]>
# Date: Fri, 8 Feb 2013 12:52:10 +0100
# Subject: [PATCH] fix serialization vulnerability
# Drop it at your_app/config/initializers/
# Remember to pass your tests/specs
module ActiveRecord
module AttributeMethods
module ClassMethods
def define_attribute_methods
return if generated_methods?
columns_hash.each do |name, column|
unless instance_method_already_implemented?(name)
if self.serialized_attributes[name]
define_read_method_for_serialized_attribute(name)
elsif create_time_zone_conversion_attribute?(name, column)
define_read_method_for_time_zone_conversion(name)
else
define_read_method(name.to_sym, name, column)
end
end
unless instance_method_already_implemented?("#{name}=")
if self.serialized_attributes[name]
define_write_method_for_serialized_attribute(name)
elsif create_time_zone_conversion_attribute?(name, column)
define_write_method_for_time_zone_conversion(name)
else
define_write_method(name.to_sym)
end
end
unless instance_method_already_implemented?("#{name}?")
define_question_method(name)
end
end
end
private
def define_write_method_for_serialized_attribute(attr_name)
method_body = <<-EOV
def #{attr_name}=(value)
if value.is_a?(String) and value =~ /^---/
raise ActiveRecordError, "You tried to assign already serialized content to #{attr_name}. This is disabled due to security issues."
end
write_attribute(:#{attr_name}, value)
end
EOV
evaluate_attribute_method attr_name, method_body, "#{attr_name}="
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment