CVE-2011-2930
Description
SQL injection in ActiveRecord quote_table_name in Ruby on Rails before 2.3.13, 3.0.10, 3.1.0.rc5 allows remote attackers to execute arbitrary SQL via crafted column name.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
SQL injection in ActiveRecord quote_table_name in Ruby on Rails before 2.3.13, 3.0.10, 3.1.0.rc5 allows remote attackers to execute arbitrary SQL via crafted column name.
Vulnerability
The quote_table_name method in ActiveRecord adapters in Ruby on Rails versions before 2.3.13, 3.0.x before 3.0.10, and 3.1.x before 3.1.0.rc5 is vulnerable to multiple SQL injection flaws. An attacker can inject arbitrary SQL commands via a crafted column name. [1]
Exploitation
An attacker can exploit this by providing a maliciously crafted column name in a request that is processed by a Rails application. No authentication is required; the attack is remote and over HTTP. By sending a specially crafted column name, the attacker can bypass input sanitization and execute arbitrary SQL queries. [1]
Impact
Successful exploitation allows the attacker to execute arbitrary SQL commands against the application's database. This can lead to unauthorized data retrieval, modification, or deletion, potentially compromising the entire database. [1]
Mitigation
The vulnerability is fixed in Rails 2.3.13, 3.0.10, and 3.1.0.rc5. Users should upgrade to these versions or later. No workaround is provided. [1]
AI Insight generated on May 23, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
activerecordRubyGems | >= 2.0.0, < 2.3.13 | 2.3.13 |
activerecordRubyGems | >= 3.0.0.beta, < 3.0.10 | 3.0.10 |
activerecordRubyGems | >= 3.1.0.beta1, < 3.1.0.rc5 | 3.1.0.rc5 |
Affected products
60cpe:2.3:a:rubyonrails:rails:2.0.0:*:*:*:*:*:*:*+ 57 more
- cpe:2.3:a:rubyonrails:rails:2.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.0.0:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.0.0:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.0.2:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.1.1:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.1.2:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.2.0:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.2.1:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.2.2:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.10:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.11:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.12:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.2:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.3:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.4:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:2.3.9:*:*:*:*:*:*:*
- 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.10:rc1:*:*:*:*:*:*
- 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:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.5:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.5:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.6:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.6:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.6:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.7:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.7:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.7:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:rc3:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.8:rc4:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc3:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc4:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.0.9:rc5:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:beta1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc1:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc2:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc3:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:rails:3.1.0:rc4:*:*:*:*:*:*
- cpe:2.3:a:rubyonrails:ruby_on_rails:3.0.4:*:*:*:*:*:*:*
Patches
18a39f411dc3cprevent sql injection attacks by escaping quotes in column names
4 files changed · +20 −3
activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb+1 −1 modified@@ -169,7 +169,7 @@ def quote(value, column = nil) end def quote_column_name(name) #:nodoc: - @quoted_column_names[name] ||= "`#{name}`" + @quoted_column_names[name] ||= "`#{name.to_s.gsub('`', '``')}`" end def quote_table_name(name) #:nodoc:
activerecord/lib/active_record/connection_adapters/mysql_adapter.rb+1 −1 modified@@ -250,7 +250,7 @@ def type_cast(value, column) end def quote_column_name(name) #:nodoc: - @quoted_column_names[name] ||= "`#{name}`" + @quoted_column_names[name] ||= "`#{name.to_s.gsub('`', '``')}`" end def quote_table_name(name) #:nodoc:
activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb+1 −1 modified@@ -148,7 +148,7 @@ def quote_string(s) #:nodoc: end def quote_column_name(name) #:nodoc: - %Q("#{name}") + %Q("#{name.to_s.gsub('"', '""')}") end # Quote date/time values for use in SQL input. Includes microseconds
activerecord/test/cases/base_test.rb+17 −0 modified@@ -67,6 +67,23 @@ def setup class BasicsTest < ActiveRecord::TestCase fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts + def test_column_names_are_escaped + conn = ActiveRecord::Base.connection + classname = conn.class.name[/[^:]*$/] + badchar = { + 'SQLite3Adapter' => '"', + 'MysqlAdapter' => '`', + 'Mysql2Adapter' => '`', + 'PostgreSQLAdapter' => '"', + 'OracleAdapter' => '"', + }.fetch(classname) { + raise "need a bad char for #{classname}" + } + + quoted = conn.quote_column_name "foo#{badchar}bar" + assert_equal("#{badchar}foo#{badchar * 2}bar#{badchar}", quoted) + end + def test_columns_should_obey_set_primary_key pk = Subscriber.columns.find { |x| x.name == 'nick' } assert pk.primary, 'nick should be primary key'
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
15- groups.google.com/group/rubyonrails-security/msg/b1a85d36b0f9dd30nvdPatchWEB
- weblog.rubyonrails.org/2011/8/16/ann-rails-3-1-0-rc6nvdPatchWEB
- www.openwall.com/lists/oss-security/2011/08/17/1nvdPatchWEB
- www.openwall.com/lists/oss-security/2011/08/19/11nvdPatchWEB
- www.openwall.com/lists/oss-security/2011/08/20/1nvdPatchWEB
- www.openwall.com/lists/oss-security/2011/08/22/13nvdPatchWEB
- www.openwall.com/lists/oss-security/2011/08/22/5nvdPatchWEB
- bugzilla.redhat.com/show_bug.cginvdPatchWEB
- github.com/rails/rails/commit/8a39f411dc3c806422785b1f4d5c7c9d58e4bf85nvdPatchWEB
- github.com/advisories/GHSA-h6w6-xmqv-7q78ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2011-2930ghsaADVISORY
- lists.fedoraproject.org/pipermail/package-announce/2011-September/065212.htmlnvdWEB
- www.debian.org/security/2011/dsa-2301nvdWEB
- www.openwall.com/lists/oss-security/2011/08/22/14nvdWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/activerecord/CVE-2011-2930.ymlghsaWEB
News mentions
0No linked articles in our index yet.