From 9340f89849606dba02f44038171f3837f883fd4e Mon Sep 17 00:00:00 2001
From: Aaron Patterson <aaron.patterson@gmail.com>
Date: Wed, 30 May 2012 15:09:13 -0700
Subject: predicate builder should not recurse for determining where columns.
 Thanks to Ben Murphy for reporting this

CVE-2012-2661
---
 .../active_record/associations/association_scope.rb   | 19 +++++++++++++++++--
 .../lib/active_record/relation/predicate_builder.rb   |  2 +-
 activerecord/test/cases/relation/where_test.rb        | 19 +++++++++++++++++++
 3 files changed, 37 insertions(+), 3 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 5a44d3a156..89a626693d 100644
--- a/activerecord/lib/active_record/associations/association_scope.rb
+++ b/activerecord/lib/active_record/associations/association_scope.rb
@@ -96,7 +96,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))
@@ -113,7 +113,7 @@ module ActiveRecord
 
             conditions.each do |condition|
               condition = interpolate(condition)
-              condition = { (table.table_alias || table.name) => condition } unless i == 0
+              condition = disambiguate_condition(table, condition) unless i == 0
 
               scope = scope.where(condition)
             end
@@ -138,6 +138,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 6a0cdd5917..cb8f903474 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -6,7 +6,7 @@ module ActiveRecord
 
         if value.is_a?(Hash)
           table = Arel::Table.new(column, engine)
-          build_from_hash(engine, value, table)
+          value.map { |k,v| build(table[k.to_sym], v) }
         else
           column = column.to_s
 
diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb
new file mode 100644
index 0000000000..90c690e266
--- /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
-- 
cgit v1.2.3


From 060c91cd59ab86583a8f2f52142960d3433f62f5 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <aaron.patterson@gmail.com>
Date: Wed, 30 May 2012 15:13:03 -0700
Subject: Strip [nil] from parameters hash. Thanks to Ben Murphy for reporting
 this!

CVE-2012-2660
---
 actionpack/lib/action_dispatch/http/request.rb     | 22 ++++++++++++++++++++++
 .../dispatch/request/query_string_parsing_test.rb  |  7 ++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index aa5ba3e8a5..6757a53bd1 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -263,6 +263,28 @@ module ActionDispatch
       LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip
     end
 
+    protected
+
+    # Remove nils from the params hash
+    def deep_munge(hash)
+      hash.each_value do |v|
+        case v
+        when Array
+          v.grep(Hash) { |x| deep_munge(x) }
+        when Hash
+          deep_munge(v)
+        end
+      end
+
+      keys = hash.keys.find_all { |k| hash[k] == [nil] }
+      keys.each { |k| hash[k] = nil }
+      hash
+    end
+
+    def parse_query(qs)
+      deep_munge(super)
+    end
+
     private
 
     def check_method(name)
diff --git a/actionpack/test/dispatch/request/query_string_parsing_test.rb b/actionpack/test/dispatch/request/query_string_parsing_test.rb
index c3f009ab15..6ea66f9d32 100644
--- a/actionpack/test/dispatch/request/query_string_parsing_test.rb
+++ b/actionpack/test/dispatch/request/query_string_parsing_test.rb
@@ -81,7 +81,12 @@ class QueryStringParsingTest < ActionDispatch::IntegrationTest
   end
 
   test "query string without equal" do
-    assert_parses({ "action" => nil }, "action")
+    assert_parses({"action" => nil}, "action")
+    assert_parses({"action" => {"foo" => nil}}, "action[foo]")
+    assert_parses({"action" => {"foo" => { "bar" => nil }}}, "action[foo][bar]")
+    assert_parses({"action" => {"foo" => { "bar" => nil }}}, "action[foo][bar][]")
+    assert_parses({"action" => {"foo" => nil}}, "action[foo][]")
+    assert_parses({"action"=>{"foo"=>[{"bar"=>nil}]}}, "action[foo][][bar]")
   end
 
   test "query string with empty key" do
-- 
cgit v1.2.3