A vulnerability has been found in a port you maintain. Please commit an update and write up a VuXML report. If you need help feel free to email ports-secur...@freebsd.org,
---------- Forwarded message ---------- From: Aaron Patterson <tenderl...@ruby-lang.org> Date: 31 May 2012 15:16 Subject: [oss-security] SQL Injection Vulnerability in Ruby on Rails (CVE-2012-2661) To: oss-secur...@lists.openwall.com SQL Injection Vulnerability in Ruby on Rails There is a SQL injection vulnerability in Active Record, version 3.0 and later. This vulnerability has been assigned the CVE identifier CVE-2012-2661. Versions Affected: 3.0.0 and ALL later versions Not affected: 2.3.14 Fixed Versions: 3.2.4, 3.1.5, 3.0.13 Impact ------ Due to the way Active Record handles nested query parameters, an attacker can use a specially crafted request to inject some forms of SQL into your application's SQL queries. All users running an affected release should upgrade immediately. Impacted code directly passes request params to the `where` method of an ActiveRecord class like this: Post.where(:id => params[:id]).all An attacker can make a request that causes `params[:id]` to return a specially crafted hash that will cause the WHERE clause of the SQL statement to query an arbitrary table with some value. Releases -------- The FIXED releases are available at the normal locations. Workarounds ----------- This issue can be mitigated by casting the parameter to an expected value. For example, change this: Post.where(:id => params[:id]).all to this: Post.where(:id => params[:id].to_s).all Patches ------- To aid users who aren't able to upgrade immediately we have provided patches for the two supported release series. They are in git-am format and consist of a single changeset. We have also provided a patch for the 3.0 series despite the fact it is unmaintained. * 3-0-params_sql_injection.patch - Patch for 3.0 series * 3-1-params_sql_injection.patch - Patch for 3.1 series * 3-2-params_sql_injection.patch - Patch for 3.2 series Please note that only the 3.1.x and 3.2.x series are supported at present. Users of earlier unsupported releases are advised to upgrade as soon as possible as we cannot guarantee the continued availability of security fixes for unsupported releases. Credits ------- Thanks to Ben Murphy for reporting the vulnerability to us, and to Chad Pyne of thoughtbot for helping us verify the fix. -- Aaron Patterson http://tenderlovemaking.com/ -- Eitan Adler
From 99f030934eb8341db333cb6783d0f42bfa57358f Mon Sep 17 00:00:00 2001 From: Aaron Patterson <aaron.patter...@gmail.com> Date: Wed, 30 May 2012 15:06:12 -0700 Subject: [PATCH] predicate builder should not recurse for determining where columns. Thanks to Ben Murphy for reporting this CVE-2012-2661 --- .../active_record/relation/predicate_builder.rb | 6 +++--- activerecord/test/cases/relation/where_test.rb | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 activerecord/test/cases/relation/where_test.rb diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 505c3f4..84e88cf 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -5,17 +5,17 @@ module ActiveRecord @engine = engine end - def build_from_hash(attributes, default_table) + def build_from_hash(attributes, default_table, check_column = true) predicates = attributes.map do |column, value| table = default_table if value.is_a?(Hash) table = Arel::Table.new(column, :engine => @engine) - build_from_hash(value, table) + build_from_hash(value, table, false) else column = column.to_s - if column.include?('.') + if check_column && column.include?('.') table_name, column = column.split('.', 2) table = Arel::Table.new(table_name, :engine => @engine) end diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb new file mode 100644 index 0000000..90c690e --- /dev/null +++ b/activerecord/test/cases/relation/where_test.rb @@ -0,0 +1,19 @@ +require "cases/helper" +require 'models/post' + +module ActiveRecord + class WhereTest < ActiveRecord::TestCase + fixtures :posts + + def test_where_error + assert_raises(ActiveRecord::StatementInvalid) do + Post.where(:id => { 'posts.author_id' => 10 }).first + end + end + + def test_where_with_table_name + post = Post.first + assert_equal post, Post.where(:posts => { 'id' => post.id }).first + end + end +end -- 1.7.5.4
From b71d4ab9d7d61ebe3411a8754e9fe93d3587704e Mon Sep 17 00:00:00 2001 From: Aaron Patterson <aaron.patter...@gmail.com> Date: Wed, 30 May 2012 15:05:19 -0700 Subject: [PATCH] predicate builder should not recurse for determining where columns. Thanks to Ben Murphy for reporting this CVE-2012-2661 --- .../associations/association_scope.rb | 17 ++++++++++++++++- .../active_record/relation/predicate_builder.rb | 6 +++--- activerecord/test/cases/relation/where_test.rb | 19 +++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 activerecord/test/cases/relation/where_test.rb diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb index 6cc401e..8e1df35 100644 --- a/activerecord/lib/active_record/associations/association_scope.rb +++ b/activerecord/lib/active_record/associations/association_scope.rb @@ -87,7 +87,7 @@ module ActiveRecord conditions.each do |condition| if options[:through] && condition.is_a?(Hash) - condition = { table.name => condition } + condition = disambiguate_condition(table, condition) end scope = scope.where(interpolate(condition)) @@ -126,6 +126,21 @@ module ActiveRecord end end + def disambiguate_condition(table, condition) + if condition.is_a?(Hash) + Hash[ + condition.map do |k, v| + if v.is_a?(Hash) + [k, v] + else + [table.table_alias || table.name, { k => v }] + end + end + ] + else + condition + end + end end end end diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 7e8ddd1..0e436e8 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -1,16 +1,16 @@ module ActiveRecord class PredicateBuilder # :nodoc: - def self.build_from_hash(engine, attributes, default_table) + def self.build_from_hash(engine, attributes, default_table, check_column = true) predicates = attributes.map do |column, value| table = default_table if value.is_a?(Hash) table = Arel::Table.new(column, engine) - build_from_hash(engine, value, table) + build_from_hash(engine, value, table, false) else column = column.to_s - if column.include?('.') + if check_column && column.include?('.') table_name, column = column.split('.', 2) table = Arel::Table.new(table_name, engine) end diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb new file mode 100644 index 0000000..90c690e --- /dev/null +++ b/activerecord/test/cases/relation/where_test.rb @@ -0,0 +1,19 @@ +require "cases/helper" +require 'models/post' + +module ActiveRecord + class WhereTest < ActiveRecord::TestCase + fixtures :posts + + def test_where_error + assert_raises(ActiveRecord::StatementInvalid) do + Post.where(:id => { 'posts.author_id' => 10 }).first + end + end + + def test_where_with_table_name + post = Post.first + assert_equal post, Post.where(:posts => { 'id' => post.id }).first + end + end +end -- 1.7.5.4
From 71f7917c553cdc9a0ee49e87af0efb7429759718 Mon Sep 17 00:00:00 2001 From: Aaron Patterson <aaron.patter...@gmail.com> Date: Wed, 30 May 2012 15:04:11 -0700 Subject: [PATCH] predicate builder should not recurse for determining where columns. Thanks to Ben Murphy for reporting this CVE-2012-2661 --- .../associations/association_scope.rb | 17 ++++++++++++++++- .../active_record/relation/predicate_builder.rb | 6 +++--- activerecord/test/cases/relation/where_test.rb | 19 +++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 activerecord/test/cases/relation/where_test.rb diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb index b3819e3..f9cffa4 100644 --- a/activerecord/lib/active_record/associations/association_scope.rb +++ b/activerecord/lib/active_record/associations/association_scope.rb @@ -75,7 +75,7 @@ module ActiveRecord conditions.each do |condition| if options[:through] && condition.is_a?(Hash) - condition = { table.name => condition } + condition = disambiguate_condition(table, condition) end scope = scope.where(interpolate(condition)) @@ -114,6 +114,21 @@ module ActiveRecord end end + def disambiguate_condition(table, condition) + if condition.is_a?(Hash) + Hash[ + condition.map do |k, v| + if v.is_a?(Hash) + [k, v] + else + [table.table_alias || table.name, { k => v }] + end + end + ] + else + condition + end + end end end end diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index a789f48..9c84d8a 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -1,16 +1,16 @@ module ActiveRecord class PredicateBuilder # :nodoc: - def self.build_from_hash(engine, attributes, default_table) + def self.build_from_hash(engine, attributes, default_table, check_column = true) predicates = attributes.map do |column, value| table = default_table if value.is_a?(Hash) table = Arel::Table.new(column, engine) - build_from_hash(engine, value, table) + build_from_hash(engine, value, table, false) else column = column.to_s - if column.include?('.') + if check_column && column.include?('.') table_name, column = column.split('.', 2) table = Arel::Table.new(table_name, engine) end diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb new file mode 100644 index 0000000..90c690e --- /dev/null +++ b/activerecord/test/cases/relation/where_test.rb @@ -0,0 +1,19 @@ +require "cases/helper" +require 'models/post' + +module ActiveRecord + class WhereTest < ActiveRecord::TestCase + fixtures :posts + + def test_where_error + assert_raises(ActiveRecord::StatementInvalid) do + Post.where(:id => { 'posts.author_id' => 10 }).first + end + end + + def test_where_with_table_name + post = Post.first + assert_equal post, Post.where(:posts => { 'id' => post.id }).first + end + end +end -- 1.7.5.4
pgp3IkQczAJf1.pgp
Description: PGP signature
_______________________________________________ freebsd-ruby@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-ruby To unsubscribe, send any mail to "freebsd-ruby-unsubscr...@freebsd.org"