Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

predicate builder should not recurse for determining where columns.

Thanks to Ben Murphy for reporting this

CVE-2012-2661
  • Loading branch information...
commit 71f7917c553cdc9a0ee49e87af0efb7429759718 1 parent fe4dfdd
@tenderlove tenderlove authored
View
17 activerecord/lib/active_record/associations/association_scope.rb
@@ -75,7 +75,7 @@ def add_constraints(scope)
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 @@ def table_name_for(reflection)
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
View
6 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
View
19 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
Please sign in to comment.
Something went wrong with that request. Please try again.