WordPress per default allows users with the administrator role to install plugins and even edit the .php files of plugins from within the admin dashboard. Although this allows for the easy modification of plugins and themes, it also allows malicious administrators to execute code on the underlying web server and install backdoors.
However, the security implications of this feature are much more severe. When an attacker can find and exploit a Cross-Site Scripting vulnerability on a WordPress site, the resulting session hijacking of the administrator account directly leads to RCE on the webserver, since an attacker can simply issue AJAX requests with the privileges of a victim administrator that write malicious code to one of the PHP files located on the server.
As an example, a CSRF to RCE vulnerability in the WordPress core (CVE-2019-9787) abused this feature.
The official WordPress hardening guide offers site owners help to mitigate such risks.
One of the recommended hardening mechanisms to enable is to place the following directive into the
wp-config.php file of the WordPress installation to be secured:
This directive effectively disables the ability for administrators to edit PHP code from within the admin dashboard. Additionally, the possibility of plugin and theme installation from within the dashboard can be disabled with the following directive:
Thus, if an attacker can exploit a Cross-Site Scripting vulnerability or can take control over an administrator account on a target WordPress site by other means, he is stuck within the admin dashboard and is unable to install a backdoor.
The vulnerability described in this blog post is an authenticated Remote Code Execution vulnerability in the WordPress core that can be exploited even if the described hardening mechanism is in place, allowing for an effective bypass. This re-enables attackers to leverage simple Cross-Site Scripting vulnerabilities to full Remote Code Execution impact on servers. The vulnerability is present in WordPress installations prior to 5.2.4.
This vulnerability is based on a Local File Inclusion (LFI) vulnerability, which also leads to a low-privileged Remote Code Execution vulnerability in WordPress 5.0.0 and prior.
A WordPress theme is simply composed of templates, .css, and .js files within the
wp-content/themes directory of a WordPress installation. The template files usually follow the WordPress template scheme: The template file responsible for rendering posts is named
post.php. The template file for rendering an author profile is called
author.php and so on.
When a visitor then for example views a post on a WordPress blog, WordPress simply includes the
post.php file within the theme directory.
However, WordPress blog post authors can define a custom file to be included for a certain post. The only limitation to this is that the file must be located within the theme directory. If that certain post is then rendered, WordPress calls PHP’s
include() on the desired template file.
Since the assumption of this blog post is that the described hardening mechanism is in place it is impossible for even administrators to place malicious code into the theme file, thus the LFI vulnerability becomes non exploitable. However, administrators can, even if all hardening mechanisms are in place, change the destination upload path for media files to the local theme directory. This in turn enables administrators to simply upload a
.txt file containing arbitrary PHP code to the theme directory and then call
include() on it. The resulting Remote Code Execution can then be leveraged to install a backdoor.
|2018/11/08||Vulnerability reported to the WordPress security team.|
|2018/11/08||WordPress triages the vulnerability.|
|2019/10/14||WordPress releases a fix in version 5.2.4.|
This blog post described what WordPress administrators can do to harden the security of their sites. The hardening mechanism described in this blog post prevents attackers from being able to leverage simple XSS flaws in plugins to Remote Code Execution impact. Although this blog post details a bypass for this hardening mechanism, it is still recommended to use them. Make sure to update your WordPress installations to 5.2.4 or later to prevent the bypass.