CVE-2013-0155: SQL Injection
Damien Mathieu (42) reports:
Unsafe Query Generation Risk in Ruby on Rails
There is a vulnerability when Active Record is used in conjunction with JSON parameter parsing. This vulnerability has been assigned the CVE identifier CVE-2013-0155.
Versions Affected: 3.x series Not affected: 2.x series Fixed Versions: 3.2.11, 3.1.10, 3.0.19
Impact ------
Due to the way Active Record interprets parameters in combination with the way that JSON parameters are parsed, it is possible for an attacker to issue unexpected database queries with "IS NULL" or empty where clauses. This issue does not let an attacker insert arbitrary values into an SQL query, however they can cause the query to check for NULL or eliminate a WHERE clause when most users wouldn't expect it.
For example, a system has password reset with token functionality:
unless params[:token].nil? user = User.findbytoken(params[:token]) user.resetpassword! end
An attacker can craft a request such that params[:token] will return [nil]. The [nil] value will bypass the test for nil, but will still add an "IN ('xyz', NULL)" clause to the SQL query.
Similarly, an attacker can craft a request such that params[:token] will return an empty hash. An empty hash will eliminate the WHERE clause of the query, but can bypass the nil? check.
Note that this impacts not only dynamic finders (findby) but also relations (User.where(:name => params[:name])).
All users running an affected release should either upgrade or use one of the work arounds immediately. All users running an affected release should upgrade immediately. Please note, this vulnerability is a variant of CVE-2012-2660, and CVE-2012-2694. Even if you upgraded to address those issues, you must take action again.
If this chance in behavior impacts your application, you can manually decode the original values from the request like so:
ActiveSupport::JSON.decode(request.body)
Releases -------- The FIXED releases are available at the normal locations.
Workarounds ----------- This problem can be mitigated by casting the parameter to a string before passing it to Active Record. For example:
unless params[:token].nil? || params[:token].tos.empty? user = User.findbytoken(params[:token].tos) user.resetpassword! end An attacker can craft a request such that params[:token] will return [nil]. The [nil] value will bypass the test for nil, but will still add an "IN ('xyz', NULL)" clause to the SQL query.
Similarly, an attacker can craft a request such that params[:token] will return an empty hash. An empty hash will eliminate the WHERE clause of the query, but can bypass the nil? check.
Note that this impacts not only dynamic finders (findby) but also relations (User.where(:name => params[:name])).
All users running an affected release should either upgrade or use one of the work arounds immediately. All users running an affected release should upgrade immediately. Please note, this vulnerability is a variant of CVE-2012-2660, and CVE-2012-2694. Even if you upgraded to address those issues, you must take action again.
If this chance in behavior impacts your application, you can manually decode the original values from the request like so:
ActiveSupport::JSON.decode(request.body)
Releases -------- The FIXED releases are available at the normal locations.
Workarounds ----------- This problem can be mitigated by casting the parameter to a string before passing it to Active Record. For example:
unless params[:token].nil? || params[:token].tos.empty? user = User.findbytoken(params[:token].tos) user.resetpassword! end
Note the parameter is still cast to a string before being sent to Active Record. This is because an array with a nil value can still bypass the tos.empty? test:
>> ['xyz', nil].tos => "xyz" >> ['xyz', nil].tos.empty? => false
Other sources
Ruby on Rails 3.0.x before 3.0.19, 3.1.x before 3.1.10, and 3.2.x before 3.2.11 does not properly consider differences in parameter handling between the Active Record component and the JSON implementation, which allows remote attackers to bypass intended database-query restrictions and perform NULL checks or trigger missing WHERE clauses via a crafted request, as demonstrated by certain "[nil]" values, a related issue to CVE-2012-2660 and CVE-2012-2694.
Affected Software
Event History
Parent advisories
This vulnerability appears in the following advisories.
Frequently Asked Questions
What is CVE-2013-0155?
CVE-2013-0155 is a vulnerability in Ruby on Rails that allows unsafe query generation when Active Record is used with JSON parameter parsing.
What is the severity of CVE-2013-0155?
CVE-2013-0155 has been classified as a moderate severity vulnerability.
How do I fix CVE-2013-0155?
To fix CVE-2013-0155, you should upgrade Active Record to version 3.2.11, 3.1.10, or 3.0.19.
Which Ruby on Rails versions are affected by CVE-2013-0155?
CVE-2013-0155 affects Ruby on Rails versions 3.0.0 to 3.0.19, 3.1.0 to 3.1.10, and 3.2.0 to 3.2.11.
Who reported the CVE-2013-0155 vulnerability?
The CVE-2013-0155 vulnerability was reported by Damien Mathieu.