High severityNVD Advisory· Published Feb 21, 2011· Updated Apr 29, 2026
CVE-2011-0448
CVE-2011-0448
Description
Ruby on Rails 3.0.x before 3.0.4 does not ensure that arguments to the limit function specify integer values, which makes it easier for remote attackers to conduct SQL injection attacks via a non-numeric argument.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
activerecordRubyGems | >= 3.0.0, < 3.0.4 | 3.0.4 |
Affected products
13cpe:2.3:a:rubyonrails:rails:3.0.0:*:*:*:*:*:*:*+ 12 more
- cpe:2.3:a:rubyonrails:rails:3.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:beta:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:beta2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:beta3:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:beta4:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:rc:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.0:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.1:pre:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.2:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.2:pre:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.3:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.4:rc1:*:*:*:*:*:*
Patches
1354da43ab0a1limit() should sanitize limit values
4 files changed · +55 −28
activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb+15 −15 modified@@ -251,6 +251,21 @@ def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key) "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{quoted_table_name} #{where_sql})" end + # Sanitizes the given LIMIT parameter in order to prevent SQL injection. + # + # +limit+ may be anything that can evaluate to a string via #to_s. It + # should look like an integer, or a comma-delimited list of integers. + # + # Returns the sanitized limit parameter, either as an integer, or as a + # string which contains a comma-delimited list of integers. + def sanitize_limit(limit) + if limit.to_s =~ /,/ + Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',') + else + Integer(limit) + end + end + protected # Returns an array of record hashes with the column names as keys and # column values as values. @@ -274,21 +289,6 @@ def delete_sql(sql, name = nil) update_sql(sql, name) end - # Sanitizes the given LIMIT parameter in order to prevent SQL injection. - # - # +limit+ may be anything that can evaluate to a string via #to_s. It - # should look like an integer, or a comma-delimited list of integers. - # - # Returns the sanitized limit parameter, either as an integer, or as a - # string which contains a comma-delimited list of integers. - def sanitize_limit(limit) - if limit.to_s =~ /,/ - limit.to_s.split(',').map{ |i| i.to_i }.join(',') - else - limit.to_i - end - end - # Send a rollback message to all records after they have been rolled back. If rollback # is false, only rollback records since the last save point. def rollback_transaction_records(rollback) #:nodoc
activerecord/lib/active_record/relation/query_methods.rb+1 −1 modified@@ -180,7 +180,7 @@ def build_arel arel = arel.having(*@having_values.uniq.reject{|h| h.blank?}) unless @having_values.empty? - arel = arel.take(@limit_value) if @limit_value + arel = arel.take(connection.sanitize_limit(@limit_value)) if @limit_value arel = arel.skip(@offset_value) if @offset_value arel = arel.group(*@group_values.uniq.reject{|g| g.blank?}) unless @group_values.empty?
activerecord/test/cases/adapter_test.rb+0 −12 modified@@ -141,16 +141,4 @@ def test_foreign_key_violations_are_translated_to_specific_exception end end end - - def test_add_limit_offset_should_sanitize_sql_injection_for_limit_without_comas - sql_inject = "1 select * from schema" - assert_no_match(/schema/, @connection.add_limit_offset!("", :limit=>sql_inject)) - assert_no_match(/schema/, @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)) - end - - def test_add_limit_offset_should_sanitize_sql_injection_for_limit_with_comas - sql_inject = "1, 7 procedure help()" - assert_no_match(/procedure/, @connection.add_limit_offset!("", :limit=>sql_inject)) - assert_no_match(/procedure/, @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)) - end end
activerecord/test/cases/base_test.rb+39 −0 modified@@ -48,6 +48,45 @@ class Boolean < ActiveRecord::Base; end class BasicsTest < ActiveRecord::TestCase fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts + def test_limit_with_comma + assert_nothing_raised do + Topic.limit("1,2").all + end + end + + def test_limit_without_comma + assert_nothing_raised do + assert_equal 1, Topic.limit("1").all.length + end + + assert_nothing_raised do + assert_equal 1, Topic.limit(1).all.length + end + end + + def test_invalid_limit + assert_raises(ArgumentError) do + Topic.limit("asdfadf").all + end + end + + def test_limit_should_sanitize_sql_injection_for_limit_without_comas + assert_raises(ArgumentError) do + Topic.limit("1 select * from schema").all + end + end + + def test_limit_should_sanitize_sql_injection_for_limit_with_comas + assert_raises(ArgumentError) do + Topic.limit("1, 7 procedure help()").all + end + end + + def test_select_symbol + topic_ids = Topic.select(:id).map(&:id).sort + assert_equal Topic.find(:all).map(&:id).sort, topic_ids + end + def test_table_exists assert !NonExistentTable.table_exists? assert Topic.table_exists?
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- groups.google.com/group/rubyonrails-security/msg/4e19864cf6ad40adnvdPatchWEB
- weblog.rubyonrails.org/2011/2/8/new-releases-2-3-11-and-3-0-4nvdPatchWEB
- secunia.com/advisories/43278nvdVendor Advisory
- github.com/advisories/GHSA-jmm9-2p29-vh2wghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2011-0448ghsaADVISORY
- lists.fedoraproject.org/pipermail/package-announce/2011-April/057650.htmlnvdWEB
- github.com/rails/rails/commit/354da43ab0a10b3b7b3f9cb0619aa562c3be8474nvdWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/activerecord/CVE-2011-0448.ymlghsaWEB
- web.archive.org/web/20201220214809/http://securitytracker.com/idghsaWEB
- securitytracker.com/idnvd
- www.vupen.com/english/advisories/2011/0877nvd
News mentions
0No linked articles in our index yet.