Digging In To The Authenticated Arbitrary File Upload Vulnerability in Elementor
Yesterday, an update was released for the 5+ million install WordPress plugin Elementor that has a changelog suggesting a security issue was addressed, “Fix: Improved code security enforcement in File Upload mechanism.” While looking into this, we found that Elementor appears to have multiple issues. We found the plugin did have an arbitrary file upload vulnerability, which you could argue is now fixed or not. Based on what we know now, we would say it is fixed, but there is still insecurity that remains, but there may be something we are missing. (Update 12/8: Elementor has released a second fix to address the remaining insecurity.) As we have been saying since April, we would recommend not using plugins from Elementor based on repeated incidents of poor security handling.
Other Providers’ Claims
It appears based on that changelog, the WordPress security provider Wordfence claimed there was a fixed or unfixed authenticated (Contributor+) arbitrary file upload to remote code execution via template import vulnerability in the plugin, which they described this way:
The Elementor Website Builder – More than Just a Page Builder plugin for WordPress is vulnerable to Remote Code Execution via file upload in all versions up to and including 3.18.0 via the template import functionality. This makes it possible for authenticated attackers, with contributor-level access and above, to upload files and execute code on the server.
They are citing as their only source for that claim, the readme.txt for the latest version, 3.18.1.
Confusingly, they are claiming that it isn’t fixed, but affects version less than the latest version:
Another WordPress security provider, Patchstack, released what seems to be a related claim, crediting Hồng Quân (luk6785 at VNPT-VCI) for discovery. Patchstack also claims to be “the official security point of contact for WordPress Elementor Website Builder plugin.”:
Despite claiming to be the official security point of contact, they are claiming to have disclosed a vulnerability with an “Incomplete patch.”
Elementor’s own contact page suggests emailing them about vulnerabilities and our interaction had them suggesting reporting through their own bug bounty program, so who knows what is going on there?
Template Import Access
Logged in to WordPress as a user with the Contributor role, the current version of Elementor, 3.18.1, allows accessing a feature to import templates for Elementor. That appears to be a security issue as when you try to import a template, you get a pop-up about enabling unfiltered file uploads. That is headlined Enable Unfiltered File Uploads and says:
Before you enable unfiltered files upload, note that such files include a security risk. Elementor does run a process to remove possible malicious code, but there is still risk involved when using such files.
If you do not enable uploading unfiltered files, any SVG or JSON (including lottie) files used in the uploaded template will not be imported.
A Contributor shouldn’t be able to enable unfiltered file uploads. That would be a security issue in itself. Them being able to upload unfiltered file uploads would also be a security issue.
Looking at the underlying code that handles the request to enable that, it checks if you have the manage_options capability, which only Administrators have, when trying to enable it:
376 377 378 | public function enable_unfiltered_files_upload() { if ( ! current_user_can( 'manage_options' ) ) { return; |
So a Contributor shouldn’t even be shown that message.
It appears there is a mismatch with whom is designed to have access to that and who actually has access.
That is largely unrelated to the vulnerability it turns out, but the vulnerability is caused by code for the template importer.
The Vulnerability
What appears to be the change made in the latest version that was supposed to address this is this code added to the function create_temp_file() in the file /core/files/uploads-manager.php:
278 279 280 281 282 | $file_name = str_replace( ' ', '', sanitize_file_name( $file_name ) ); if ( empty( $file_name ) ) { return new \WP_Error( 'invalid_file_name', 'Invalid file name.' ); } |
That passes the name of a file through the sanitize_file_name() function. How would that restrict arbitrary file uploads, though? It wouldn’t. What it does limit is directory traversal.
The code that runs after that saves a file to a directory with a random name:
284 285 286 287 288 289 290 291 292 293 294 295 296 297 | $temp_filename = $this->create_unique_dir() . $file_name; /** * Temp File Path * * Allows modifying the full path of the temporary file. * * @since 3.7.0 * * @param string full path to file */ $temp_filename = apply_filters( 'elementor/files/temp-file-path', $temp_filename ); file_put_contents( $temp_filename, $file_content ); // phpcs:ignore |
Before the new code was added, the file could be moved out of the directory using directory traversal, so an attacker could place it in another location where they know the address.
There are no other restrictions on the file, so arbitrary files can still be added.
We confirmed this was exploitable.
We would say that is fixed, unless someone is able to show how an attacker could find the name of the directory.
That is accessible by those who can access the Elementor editor, so normally Contributors.
Plugin Security Scorecard Grade for Elementor
Checked on August 29, 2024See issues causing the plugin to get less than A+ grade