Skip to content

Instantly share code, notes, and snippets.

@isabanin
Created June 14, 2012 14:42
Show Gist options
  • Save isabanin/2930759 to your computer and use it in GitHub Desktop.
Save isabanin/2930759 to your computer and use it in GitHub Desktop.
Monkey-patching CVE-2012-2694 and CVE-2012-2695 security vulnerabilities in Rails 2.3 series
#
# About the vulnerability:
#
# http://seclists.org/oss-sec/2012/q2/503
#
# This code is for Rails 2.3 series only. Tested on 2.3.14.
#
# Put this file into lib/rails_patches directory
# then include it in one of your config/initializers.
#
module ActionController
class Request < Rack::Request
private
def deep_munge(hash)
keys = hash.keys.find_all { |k| hash[k] == [nil] }
keys.each { |k| hash[k] = nil }
hash.each_value do |v|
case v
when Array
v.grep(Hash) { |x| deep_munge(x) }
v.compact!
when Hash
deep_munge(v)
end
end
hash
end
# Convert nested Hashs to HashWithIndifferentAccess and replace
# file upload hashs with UploadedFile objects
def normalize_parameters(value)
case value
when Hash
if value.has_key?(:tempfile)
upload = value[:tempfile]
upload.extend(UploadedFile)
upload.original_path = value[:filename]
upload.content_type = value[:type]
upload
else
h = {}
value.each { |k, v| h[k] = normalize_parameters(v) }
deep_munge(h.with_indifferent_access)
end
when Array
value.map { |e| normalize_parameters(e) }
else
value
end
end
end
end
#
# About the vulnerability:
#
# http://seclists.org/oss-sec/2012/q2/504
#
# This code is for Rails 2.3 series only. Tested on 2.3.14.
#
# Put this file into lib/rails_patches directory
# then include it in one of your config/initializers.
#
module ActiveRecord
class Base
protected
class << self
def sanitize_sql_hash_for_conditions(attrs, default_table_name = quoted_table_name, top_level = true)
attrs = expand_hash_conditions_for_aggregates(attrs)
conditions = attrs.map do |attr, value|
table_name = default_table_name
if not value.is_a?(Hash)
attr = attr.to_s
# Extract table name from qualified attribute names.
if attr.include?('.') and top_level
attr_table_name, attr = attr.split('.', 2)
attr_table_name = connection.quote_table_name(attr_table_name)
else
attr_table_name = table_name
end
attribute_condition("#{attr_table_name}.#{connection.quote_column_name(attr)}", value)
elsif top_level
sanitize_sql_hash_for_conditions(value, connection.quote_table_name(attr.to_s), false)
else
raise ActiveRecord::StatementInvalid
end
end.join(' AND ')
replace_bind_variables(conditions, expand_range_bind_variables(attrs.values))
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment