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.
Applications that use MemCacheStore and RedisCacheStore may be vulnerable to unintended unmarshalling (also known as deserialization) of user-provided objects.
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: activesupport
- GitHub repository:
https://github.com/rails/rails - Published package: The individual activesupport gem or the entire Rails Framework gem (which includes activesupport).
- Package manager: gem
Vulnerability Info
The exploit may occur when untrusted user input is written to the cache store using the raw:true parameter. When the data are read from the cache, the user input may be mistakenly unmarshalled, that is, reconstituted into an object, instead of remaining as plain text. A malicious user can use this exploit to cause remote code execution.
Steps to Reproduce
1. Set up a vulnerable version of Rails and create a simple controller that stores and retrieves data using the raw:true parameter. Note how untrusted data comes through the params[:user_input]:
class DemoController < ApplicationController
def index
# Untrusted input from a query parameter
untrusted_string = params[:user_input]
# Store the data using `raw: true`
Rails.cache.write("demo", untrusted_string, raw: true)
# Fetch the data from the cache (vulnerable behavior)
data = Rails.cache.fetch("demo", raw: true)
# Render the fetched data
render plain: "Cached data: #{data}"
end
end
2. Also note the subsequent use of the Rails.cache.fetch() function. With this vulnerability, the raw:true parameter is ignored and the framework unmarshalls the data coming from the cache in all cases—even when the data should remain in its raw form.
Workarounds
Developers can avoid using raw:true with untrusted input or can take steps to sanitize the input before storing it in the cache.
Credits
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.