Overview
Ruby on Rails (often called Rails) is a web application framework written in Ruby that emphasizes convention over configuration and the principle of "don't repeat yourself" (DRY). It provides developers with a structured and efficient way to build database-backed web applications through pre-built patterns for rapid development.
There is a vulnerability in the serialized attribute handling code in Ruby on Rails 2.3 and 3.0. Applications that allow users to directly assign to the serialized fields in their models are at risk of Remote Code Execution vulnerabilities.
Remote code execution flaws are among the Top 10 Open Web Application Security Project (OWASP) vulnerabilities. They are among the most potentially damaging of vulnerabilities because injected, remotely executed code:
- can access internal application objects/methods
- can often bypass security controls
- may persist across sessions
- can often pivot to gain OS-level access.
All users running an affected release should apply the workaround or upgrade immediately.
Details
Module Info
- Product: Ruby on Rails Framework
- Affected packages: activerecord
- GitHub repository:
https://github.com/rails/rails - Published package: The individual activerecord gem or the entire Rails Framework gem (which includes activerecord).
- Package manager: gem
Vulnerability Info
Storing objects to a BLOB column in the database can be accomplished through the default YAML coder and with the help of the serialize class method. The method is part of the ActiveRecord class in the Active Record gem.
If a developer passes user input directly to this method, it is possible for a specially crafted request to cause the application to deserialize arbitrary, dangerous YAML. This may result in remote code execution (or denial of service).
Steps To Reproduce
The code below shows code vulnerable to this exploit. First, here is a class with serialization set up for the “tags” class attribute (which corresponds to the “tags” field name). It sets up automatic serialization and deserialization for the field.
class Post < ActiveRecord::Base
serialize :tags
end
Next, if an attacker can control the YAML data being stored, they can craft malicious YAML that creates dangerous Ruby objects.
In this case, take untrusted user input, assign it directly to the field and save it.
post = Post.new
post.tags = params[:tags]
post.save
The unserialization process occurs during the read operation, as shown below, and can result in the remote code execution (or denial of service).
working_tags = post.tags
Workarounds
One way to work around this issue is to whitelist fields that can be assigned (via attr_accessible) and explicitly exclude the serialized column.
class Post < ActiveRecord::Base
serialize :tags
# because :tags isn't included in the accessible list, it will be protected from assignment by attackers.
attr_accessible :title, :content
end
Versions of Rails higher than 3 introduce Strong Parameters, which accomplish a similar function to attr_accessible.
Credits
- Tobias Kraze
Mitigation
Users of affected versions of Ruby on Rails should follow one of the following mitigations:
- Upgrade to a corrected version.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.