diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-08-06 21:17:19 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-08-18 14:07:37 -0300 |
commit | 306dc1a499908ba105e6b0fe8b8e01824c5e04d7 (patch) | |
tree | a8ec4a562ea9ff154563214dc3dbe5f28b7f454e | |
parent | e759b5277e404cb0ca8353d0c6eba8a5c471af41 (diff) | |
download | rails-306dc1a499908ba105e6b0fe8b8e01824c5e04d7.tar.gz rails-306dc1a499908ba105e6b0fe8b8e01824c5e04d7.tar.bz2 rails-306dc1a499908ba105e6b0fe8b8e01824c5e04d7.zip |
Check attributes passed to create_with and where
If the request parameters are passed to create_with and where they can
be used to do mass assignment when used in combination with
Relation#create.
Fixes CVE-2014-3514
Conflicts:
activerecord/lib/active_record/relation/query_methods.rb
3 files changed, 45 insertions, 2 deletions
diff --git a/activemodel/lib/active_model/forbidden_attributes_protection.rb b/activemodel/lib/active_model/forbidden_attributes_protection.rb index 7468f95548..b4fa378601 100644 --- a/activemodel/lib/active_model/forbidden_attributes_protection.rb +++ b/activemodel/lib/active_model/forbidden_attributes_protection.rb @@ -23,5 +23,6 @@ module ActiveModel attributes end end + alias :sanitize_forbidden_attributes :sanitize_for_mass_assignment end end diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index c8f382ad78..067966321d 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -1,9 +1,12 @@ require 'active_support/core_ext/array/wrap' +require 'active_model/forbidden_attributes_protection' module ActiveRecord module QueryMethods extend ActiveSupport::Concern + include ActiveModel::ForbiddenAttributesProtection + # WhereChain objects act as placeholder for queries in which #where does not have any parameter. # In this case, #where must be chained with #not to return a new relation. class WhereChain @@ -574,7 +577,10 @@ WARNING end def where!(opts, *rest) # :nodoc: - references!(PredicateBuilder.references(opts)) if Hash === opts + if Hash === opts + opts = sanitize_forbidden_attributes(opts) + references!(PredicateBuilder.references(opts)) + end self.where_values += build_where(opts, rest) self @@ -723,7 +729,13 @@ WARNING end def create_with!(value) # :nodoc: - self.create_with_value = value ? create_with_value.merge(value) : {} + if value + value = sanitize_forbidden_attributes(value) + self.create_with_value = create_with_value.merge(value) + else + self.create_with_value = {} + end + self end diff --git a/activerecord/test/cases/forbidden_attributes_protection_test.rb b/activerecord/test/cases/forbidden_attributes_protection_test.rb index 981a75faf6..f4e7646f03 100644 --- a/activerecord/test/cases/forbidden_attributes_protection_test.rb +++ b/activerecord/test/cases/forbidden_attributes_protection_test.rb @@ -66,4 +66,34 @@ class ForbiddenAttributesProtectionTest < ActiveRecord::TestCase person = Person.new assert_nil person.assign_attributes(ProtectedParams.new({})) end + + def test_create_with_checks_permitted + params = ProtectedParams.new(first_name: 'Guille', gender: 'm') + + assert_raises(ActiveModel::ForbiddenAttributesError) do + Person.create_with(params).create! + end + end + + def test_create_with_works_with_params_values + params = ProtectedParams.new(first_name: 'Guille') + + person = Person.create_with(first_name: params[:first_name]).create! + assert_equal 'Guille', person.first_name + end + + def test_where_checks_permitted + params = ProtectedParams.new(first_name: 'Guille', gender: 'm') + + assert_raises(ActiveModel::ForbiddenAttributesError) do + Person.where(params).create! + end + end + + def test_where_works_with_params_values + params = ProtectedParams.new(first_name: 'Guille') + + person = Person.where(first_name: params[:first_name]).create! + assert_equal 'Guille', person.first_name + end end |