Navigation Menu

Skip to content

Commit

Permalink
predicate builder should not recurse for determining where columns.
Browse files Browse the repository at this point in the history
Thanks to Ben Murphy for reporting this

CVE-2012-2661
  • Loading branch information
tenderlove committed May 30, 2012
1 parent a74b6a0 commit b71d4ab
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 4 deletions.
17 changes: 16 additions & 1 deletion activerecord/lib/active_record/associations/association_scope.rb
Expand Up @@ -87,7 +87,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))
Expand Down Expand Up @@ -126,6 +126,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
6 changes: 3 additions & 3 deletions 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
Expand Down
19 changes: 19 additions & 0 deletions 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

0 comments on commit b71d4ab

Please sign in to comment.