public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Added SQL escaping for :limit and :offset [#288 state:closed] (Aaron Bedra, 
Steven Bristol, Jonathan Wiess)
dhh (author)
Sat May 31 16:57:46 -0700 2008
commit  ef0ea782b1f5cf7b08e74ea3002a16c708f66645
tree    e5bafb8aacf682d2df36d598a14ae1f623c5a258
parent  a6e79083273dfb1a62aa8ff02db07454c65729ff
...
106
107
108
109
 
110
111
 
112
113
 
 
 
 
 
114
115
116
...
106
107
108
 
109
110
 
111
112
113
114
115
116
117
118
119
120
121
0
@@ -106,11 +106,16 @@ module ActiveRecord
0
       #  SELECT * FROM suppliers LIMIT 10 OFFSET 50
0
       def add_limit_offset!(sql, options)
0
         if limit = options[:limit]
0
-          sql << " LIMIT #{limit}"
0
+          sql << " LIMIT #{sanitize_limit(limit)}"
0
           if offset = options[:offset]
0
-            sql << " OFFSET #{offset}"
0
+            sql << " OFFSET #{offset.to_i}"
0
           end
0
         end
0
+        sql
0
+      end
0
+
0
+      def sanitize_limit(limit)
0
+        limit.to_s[/,/] ? limit.split(',').map{ |i| i.to_i }.join(',') : limit.to_i
0
       end
0
 
0
       # Appends a locking clause to an SQL statement.
...
104
105
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
0
@@ -104,4 +104,24 @@ class AdapterTest < ActiveRecord::TestCase
0
     end
0
   end
0
 
0
+  def test_add_limit_offset_should_sanitize_sql_injection_for_limit_without_comas
0
+    sql_inject = "1 select * from schema"
0
+      assert_equal " LIMIT 1", @connection.add_limit_offset!("", :limit=>sql_inject)
0
+    if current_adapter?(:MysqlAdapter)
0
+      assert_equal " LIMIT 7, 1", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
0
+    else
0
+      assert_equal " LIMIT 1 OFFSET 7", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
0
+    end
0
+  end
0
+
0
+  def test_add_limit_offset_should_sanitize_sql_injection_for_limit_with_comas
0
+    sql_inject = "1, 7 procedure help()"
0
+    if current_adapter?(:MysqlAdapter)
0
+      assert_equal " LIMIT 1,7", @connection.add_limit_offset!("", :limit=>sql_inject)
0
+      assert_equal " LIMIT 7, 1", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
0
+    else
0
+      assert_equal " LIMIT 1,7", @connection.add_limit_offset!("", :limit=>sql_inject)
0
+      assert_equal " LIMIT 1,7 OFFSET 7", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
0
+    end
0
+  end
0
 end

Comments