You are currently viewing CVE-2021-45040
CVE-2021-45040 webshell

CVE-2021-45040

On 14 Dec 2021, we have reported a vulnerability (CVE-2021-45040) for the Spatie media-library-pro library. In short, the Spatie media-library-pro library through 1.17.10 and 2.x through 2.1.6 for Laravel allows remote attackers to upload executable files via the uploads route.

Introduction

Media Library Pro is a paid add-on package for Spatie Laravel Media Library. Laravel Media Library Pro intended to solve file upload challenges for PHP developers by providing a convenient “Temporary Upload” function and frontend package for Blade, Livewire, React, and Vue.

The “Temporary Upload” function of Media Library Pro also provides a route macro “Route::mediaLibrary()” which will register a route at “media-library-pro/uploads”. This is the default URI endpoint but can be changed by the developer. It accepts POST requests to upload files and store the uploaded files inside a temporary directory. However, this route Marco has NO authentication enabled by default for Laravel API-style design.

This temporary upload route accepts 3 POST parameters including uuid, name, and file:

  • uuid is a random string in this format: c46c4540-5803-11ec-970b-00155d4e8236, and it is possible to generate a random uuid using Linux command “uuid”
  • name represents the file name which is an arbitrary string
  • file is the actual file to be upload.

Unauthenticated Arbitrary File Upload concern (CVE-2021-45040)

After a successful POST request to the route “media-library-pro/uploads”, a JSON payload including “original_url” string will be returned. Therefore, the user can directly access this file. If the server is not hardened properly, this approach opened up the possibilities and lets the attacker upload a web shell because there is no filtering of file type/extension at the temporary upload stage.

Other concerns

In addition to the above “unauthenticated arbitrary file upload” issue, there is a lack of file name length protection and rate-limiting which may also open possibilities of DDoS attack or other potential issues.

Furthermore, the Media Library Pro library is a PHP software library that may be included by the other software or website, it may impact some of the website or other software packages. Therefore, it can also be classified as SupplyChain vulnerability.

Simulation environment for CVE-2021-45040

Below are some components to simulate a vulnerable environment (CVE-2021-45040):

Below are instructions to setup the simulate a vulnerable environment. Firstly, we need to create a basic project skeleton:

composer create-project --prefer-dist laravel/laravel laravel8_medialibrarypro

Then, we need to install Laravel media Library, generate corresponding configuration and perform database migration. A complete documentation is available here.

cd laravel8_medialibrarypro/
composer require "spatie/laravel-medialibrary:^9.0.0"
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="migrations"
php artisan migrate
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="config"

Before proceed the following instructions, we need to configure the repository and add license, you can refer to the documentation here. Then, we can proceed to install Laravel media library pro and generate its configuration.

composer require spatie/laravel-medialibrary-pro
php artisan vendor:publish --provider="Spatie\MediaLibraryPro\MediaLibraryProServiceProvider" --tag="media-library-pro-migrations"

Next, we can add the route and run the service:

echo 'Route::mediaLibrary();' to routes/web.php
php artisan serve

If everything is setup correctly, you will be able to upload webshell PHP file to the server, and able to check the value of “original_url”.

CVE-2021-45040 postman upload
CVE-2021-45040 Postman upload screen

Finally, we can access the webshell and run arbitrary command as the user of web service.

CVE-2021-45040 webshell
CVE-2021-45040 webshell screen

Solution

In this section, we will cover some possible solutions for CVE-2021-45040.

If you are using Apache or Nginx, you can limit attacker execute the PHP webshell using configuration directives:

We will also discuss another approach for each problem, but you need to do more customization:

Unauthenticated upload

Do not use Route macro, and add “auth:api” middleware. You may refer to the following sample:

Route::post('media-library/uploads', TemporaryUpload::class)
    ->name('media-library-uploads')
    ->middleware(['auth:api'])

User able to upload any kind of files

Adapt your new controller class, and perform validation.

User can directly access the original file

Extend TemporaryUpload model, force image conversion, and delete the original file.

Original file name is returned in Json response

Extend Media model, and override the getOriginalUrlAttribute function to return converted file.

Predicatable path may allow brute-forcing

Extend the file_namer & path_generator class to generate the non-predictable path. One thing to note is that you cannot generate random paths or filenames.

Rate-Limiting

Add a new middleware using RateLimiter.

Summary

To summarize, the default implementation and documentation of Laravel medialibrary-pro allow “Unauthenticated Arbitrary File Upload” which may lead to uploading a PHP web shell, and potentially take over the entire system. We have discussed some possible solutions, and some best practices when designing file upload functions for a web application.

Updated on 21 Mar 2022:

Laravel Media Library Pro teams released v.2.1.11 & v1.17.12 which fixed all our reported issues, and we have validated the results. We would like to appreciate the effort and their commitment to security.

Updated on 19 Mar 2022:

Laravel Media Library Pro teams released v.2.1.8 which fix the issues, and we will work with them to validate the result and provide our feedback.

Updated on 18 Mar 2022:

We have received tons of replies regarding the file upload best practices and concerns. So, we are preparing additional materials including blog posts and youtube for this topic. Stay tuned!

Updated on 16 Mar 2022:

Laravel Media Library Pro teams are working on a fix, and the new changes introduce the following new features:

  • Configurable upload file types using both mime types and file extension as validation
  • Generate random paths using TemporaryUploadPathGenerator
  • Recommend “use S3 for file uploads” as a best practice in documentation

Official CVE Link:

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45040

Full Disclosure Link:

https://seclists.org/fulldisclosure/2022/Mar/15