Issue Description

The Paperclip library has a concept of ‘IO adapters’ that provide multiple ways a ‘file’ can be passed to the Paperclip library so that it can do what it does best. The vulnerability affects two of Paperclip’s IO adapters that accept URLs as attachment data:

When these adapters are used, Paperclip acts as a proxy and downloads the file from the website URI that is passed in.

The ‘http_url_proxy_adapter.rb’ is invoked if the provided file/attachment data starts with ‘http://’ or ‘https://’. This behavior is not currently documented by Paperclip and the library does not perform any validation to protect against Server Side Request Forgery (SSRF) exploits.

Sample Vulnerable Rails code using Paperclip:

The following code example shows a Rails controller that takes in an ‘attachment’ request parameter and passes to the ‘GenericAttachment’ model that has declared Paperclip’s ‘has_attached_file’ method.

class GenericUploadController < ActionController::Base

..snip.. def create

GenericAttachment.create(:attachment => params[:attachment])

..snip..

end class GenericAttachment < ActiveRecord::Base

has_attached_file :attachment

Proof of Concept Exploit

Typically, the ‘attachment’ multipart form parameter would contain the file contents of the file (either binary or base64 encoded). To trigger the vulnerable adapter you would instead submit a URL.

POST /upload HTTP/1.1

Host: example.com

..snip.. — — — WebKitFormBoundaryGB91jEIcBxpCcDww Content-Disposition: form-data; name=”attachment”; http://169.254.169.254/latest/

The URL submitted in the ‘attachment’ parameter would be parsed by the ‘http_url_proxy_adapter’ and the AWS EC2 metadata IP, 169.254.169.254 (non-routable outside of the AWS EC2 instance), would be requested and stored as the attachment file. Depending on the vulnerable application and allowed content-types, it may be possible for an attacker to recover this response data by leveraging other features in the application that allow viewing of the file data.

The ‘uri_adapter’ IO adapter (http_url_proxy_adapter inherits from uri_adapter), is invoked when the attachment data is a ‘URI’ class type. A example snippet of vulnerable code would look something like the following:

class GenericUploadController < ActionController::Base

..snip.. def create

GenericAttachment.create(:attachment =>

URI(params[:attachment]))

..snip..

end

Unlike the ‘http_url_proxy_adapter’, the ‘uri_adapter’ behavior is documented here. The adapter is susceptible to SSRF if an unvalidated URL is accepted from user input, set as a URI object and set as the attachment data on the model.

What’s the impact?

The ‘http_url_proxy_adapter’ can be invoked directly from HTTP request parameters and therefore all applications that use Paperclip without additional validation of user input would be susceptible to SSRF attacks by default. The ‘uri_adapter’ could still be exploited to perform SSRF attacks, but this vulnerability would need to be introduced by a developer since a URI object must be created and passed in as the attachment data.

Server-Side Request Forgery (SSRF) vulnerabilities could be exploited to:

Perform GET requests to hosts located on the internal network or local interfaces

Steal AWS access tokens by performing requests to EC2 metadata servers

Perform requests to hosts on the internal network that do not require authentication

Retrieve the requested data if the attachment is retrievable within the application

Perform GET requests to internet accessible systems using the vulnerable server’s egress IP

Port scan internal network

SSRF vulnerabilities give attackers a pivot point into the victim’s internal network and could typically be abused to expand access to the victim’s network and steal secrets.