Blob Blame History Raw
From 176af7eff2e33b331c92febbeda98123da1151f3 Mon Sep 17 00:00:00 2001
From: Ernie Miller <ernie@erniemiller.org>
Date: Fri, 8 Jun 2012 16:42:01 -0400
Subject: [PATCH] Additional fix for CVE-2012-2661

While the patched PredicateBuilder in 3.0.13 prevents a user
from specifying a table name using the `table.column` format,
it doesn't protect against the nesting of hashes changing the
table context in the next call to build_from_hash. This fix
covers this case as well.
---
 .../active_record/relation/predicate_builder.rb    |    6 +++---
 activerecord/test/cases/relation/where_test.rb     |    6 ++++++
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 84e88cf..e74ba73 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, check_column = true)
+    def build_from_hash(attributes, default_table, allow_table_name = true)
       predicates = attributes.map do |column, value|
         table = default_table
 
-        if value.is_a?(Hash)
+        if allow_table_name && value.is_a?(Hash)
           table = Arel::Table.new(column, :engine => @engine)
           build_from_hash(value, table, false)
         else
           column = column.to_s
 
-          if check_column && column.include?('.')
+          if allow_table_name && 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
index 90c690e..b9eef1d 100644
--- a/activerecord/test/cases/relation/where_test.rb
+++ b/activerecord/test/cases/relation/where_test.rb
@@ -11,6 +11,12 @@ module ActiveRecord
       end
     end
 
+    def test_where_error_with_hash
+      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
-- 
1.7.5.4