During a security auditing of the Ruby on Rails source and its dependencies, we discovered two ways to exploit ActiveStorage’s image transformation functionality. In this blog post, we will tell you this story. When we did this security audit in April 2021 the versions of the components involved were: activestorage 220.127.116.11, image_processing 1.12.1, and mini_magick 4.11.0. The image_processing library was the main recommendation for image analysis and transformations at that time.
The finding process
We decided to analyze the Ruby on Rails (RoR) framework because it is very popular and we have some experience in auditing RoR applications. For this reason, we had the idea to take a look at the RoR core to see how things are implemented and see if we could find an interesting attack surface. We accomplished the whole activity as a small, internal project.
The first thing we did was to map the main components (activerecord, activestorage, etc) and try to understand their purpose and main use.
We then mapped the external libraries used by the RoR core. One particular library (image_processing) caught our attention because it deals with image processing and it is common to see some vulnerabilities reported in image processors libraries or tools.
The next step was to understand how RoR uses it and the interface provided by it. The image_processing is used by the ActiveStorage image transformation functionality to create variants for an image .
By analyzing the flow from the parameters for the variant() and preview() APIs  to the image_processing library, we discovered two problems:
- Code Injection – Depending on how the variant is created, if a user-supplied value is used, it is possible to call arbitrary methods using the send() method. An attacker could invoke the method eval() and pass a string to be evaluated as code.
- Argument Injection – Depending on how the variant is created, if a user-supplied value is used, it is possible to inject arbitrary arguments into the command to be executed (ImageMagick’s convert by default). The injection of arbitrary arguments could be used to write data to arbitrary files in the system and consequently achieve code execution.
To make it clear, we only investigated the exploitation of these issues when the code had the patterns presented in the advisory . At the time of the report, there was no documentation to warn developers about the dangers of passing user-supplied data to the affected methods (variant/preview) without validation.
The report process
We reported these vulnerabilities in April 2021 via HackerOne according to Rails security policy. The Rails team implemented some fixes and improvements, make sure to check their security notice for more details.
Authors of this article:
Gabriel Quadros – Senior Information Security Analyst
Ricardo Silva – Information Security Analyst