From 37d5e2cf429f6be937aeab1cf940ebc6e6c6d290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Thu, 5 Jun 2014 14:08:40 -0300 Subject: [PATCH] Fix SQL injection when querying against ranges and bitstrings Fix CVE-2014-3483 and protect against CVE-2014-3482. --- .../lib/active_record/connection_adapters/postgresql/quoting.rb | 7 ++++--- .../lib/active_record/connection_adapters/postgresql_adapter.rb | 2 +- activerecord/test/cases/adapters/postgresql/quoting_test.rb | 6 ++++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb index 7efdd8a..06b6478 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -23,7 +23,8 @@ module ActiveRecord case value when Range if /range$/ =~ sql_type - "'#{PostgreSQLColumn.range_to_string(value)}'::#{sql_type}" + escaped = quote_string(PostgreSQLColumn.range_to_string(value)) + "#{escaped}::#{sql_type}" else super end @@ -70,8 +71,8 @@ module ActiveRecord when 'xml' then "xml '#{quote_string(value)}'" when /^bit/ case value - when /^[01]*$/ then "B'#{value}'" # Bit-string notation - when /^[0-9A-F]*$/i then "X'#{value}'" # Hexadecimal notation + when /\A[01]*\Z/ then "B'#{value}'" # Bit-string notation + when /\A[0-9A-F]*\Z/i then "X'#{value}'" # Hexadecimal notation end else super diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 9ac5af8..6bb0957 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -771,7 +771,7 @@ module ActiveRecord FEATURE_NOT_SUPPORTED = "0A000" # :nodoc: def exec_no_cache(sql, binds) - @connection.async_exec(sql) + @connection.async_exec(sql, []) end def exec_cache(sql, binds) diff --git a/activerecord/test/cases/adapters/postgresql/quoting_test.rb b/activerecord/test/cases/adapters/postgresql/quoting_test.rb index b342964..0cafb63 100644 --- a/activerecord/test/cases/adapters/postgresql/quoting_test.rb +++ b/activerecord/test/cases/adapters/postgresql/quoting_test.rb @@ -52,6 +52,12 @@ module ActiveRecord c = Column.new(nil, nil, 'text') assert_equal "'666'", @conn.quote(fixnum, c) end + + def test_quote_range + range = "1,2]'; SELECT * FROM users; --".."a" + c = PostgreSQLColumn.new(nil, nil, OID::Range.new(:integer), 'int8range') + assert_equal "[1,2]''; SELECT * FROM users; --,a]::int8range", @conn.quote(range, c) + end end end end -- 2.0.0