CVE-2019-5418
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 possible file content disclosure vulnerability in the actionview package, which is a core gem (package) included in all versions of the framework. By crafting a malicious accept header and calling the render file function, an attacker can render arbitrary files thereby seeing the file content.
Rendering a template does not suffer from this exploit.
This exploit is in the category of Information Exposure and, as such, is considered to have High severity. Information Exposure fits into two of the Top 10 Open Web Application Security Project (OWASP) vulnerabilities: Broken Access Control and Security Misconfiguration.
Possible exposure may include:
- application configuration details
- server information (e.g., versions of frameworks, libraries, or OS)
- user data, including passwords, personal information
- and API keys.
Since this issue affects all versions of the Ruby on Rail Framework, all users running an affected release should apply the workaround or upgrade immediately.
Details
Module Info
- Product: Ruby on Rails Framework
- Affected packages: actionview
- GitHub repository:
https://github.com/rails/rails - Published package: The individual actionview gem or the entire Rails Framework gem (which includes actionview).
- Package manager: gem
- Fixed in:
- HeroDevs 6.1 LTS
- HeroDevs 5.2 LTS
- HeroDevs 4.2 LTS
- HeroDevs 3.2 LTS
- HeroDevs 2.3 LTS
Vulnerability Info
This vulnerability affects the actionview gem when using the render file: option without specifying a format. When Rails receives a request with a specially crafted Accept header, it may disclose the contents of arbitrary files on the system instead of just rendering the intended template file.
The impact is limited to calls to render that render file contents without a specified accept format. Impacted code in a controller looks something like this:
class UserController < ApplicationController
def index
render file: "#{Rails.root}/some/file" # Vulnerable
end
end
When this vulnerability is exploited, an attacker can manipulate the Accept header to potentially read sensitive files like:
- Application configuration files containing secrets
- Database configuration files
- System files outside the application directory
Rendering templates (as opposed to files) is not impacted by this vulnerability because templates contain proper security checks for format validation. For example, this is safe:
class UserController < ApplicationController
def index
render "index" # Safe - renders a template
end
end
Steps To Reproduce
The impact is limited to calls to render that render file contents without a specified accept format. Impacted code in a controller looks something like this:
class UserController < ApplicationController
def index
render file: "#{Rails.root}/some/file"
end
end
Rendering templates as opposed to files is not impacted by this vulnerability (templates contain proper security checks).Workarounds
There are two ways to mitigate this vulnerability without upgrading:
1. Explicitly Specify Format: The recommended approach is to always specify the format when rendering files. This prevents the header manipulation exploit by enforcing a specific content type:
class UserController < ApplicationController
def index
# Before (vulnerable):
# render file: "#{Rails.root}/some/file"
# After (safe, format specified):
render file: "#{Rails.root}/some/file", formats: [:html]
end
end
2. Filter Request Formats: For applications that cannot modify all render calls, you can implement a global filter in an initializer that validates format types:
$ cat config/initializers/formats_filter.rb
# frozen_string_literal: true
ActionDispatch::Request.prepend(Module.new do
def formats
super().select do |format|
format.symbol || format.ref == "*/*"
end
end
end)
This global approach filters out potentially malicious format requests before they reach the rendering engine, though explicitly specifying formats as in the first approach is preferred.
Note: When using either workaround, thoroughly test your application as changing format handling may affect how content is served to clients.
Credits
- John Hawthorn (john@hawthorn.email of GitHub)
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.