A severe security vulnerability—specifically an XXE Injection vulnerability—has been discovered in WordPress.
This bug is pretty severe, and allows attackers to remotely steal files from any WordPress host.
This vulnerability also affects WordPress versions prior to 5.7.1.
What Do XXE Injection Vulnerability Attacks Do?
Remote attackers are able to perform the following attacks:
- Disclosure of Arbitrary Files: This means that basically the contents of any file on a WordPress host system can be retrieved. One such example of a file that can be retrieved is wp-config.php, which contains sensitive database credentials.
- Server-Side Request Forgery (SSRF): In this attack, hackers use the WordPress installation to make HTTP requests. If the security of certain environments is not fully locked down, this may have a serious impact.
Thankfully, WordPress issued a security patch on April 14, 2021.
Sonar Source reported the following technical details behind the attack:
Technical Details
In this section we take a closer look at the technical details of the vulnerability. First we briefly revisit what an XXE vulnerability is. Following that, we dive into the vulnerability our analyzer reported in the WordPress core by looking at where it is located in the code, and why it became exploitable again in PHP 8 even though there was an effort to prevent such vulnerabilities in the affected code lines. Finally, we demonstrate how it can be exploited by attackers by using specially crafted input to extract the wp-config.php file, and how the vulnerability is prevented.
XML External Entity (XXE) Vulnerabilities
XML offers the possibility to define custom entities that can be reused throughout a document. This can, for example, be used to avoid duplication. The following code defines an entity myEntity for further usage.
<!ENTITY myEntity “a long value” > ]>
<myDoc>
<foo>&myEntity;</foo>
<bar>&myEntity;</bar>
</myDoc>
The value of defined entities can also stem from an external source referenced by a URI. In this case, they are called external entities:
<!ENTITY myExternalEntity SYSTEM “http://…..com/value.txt” > ]>
<myDoc>
<foo>&myExternalEntity;</foo>
<myDoc>
XXE attacks misuse this feature. They are possible when a loosely configured XML parser is run on user-controlled content. Loosely configured usually means that all entities are substituted with their corresponding value in the result. For example, in the last sample, if an attacker would supply file:///var/www/wp-config.php as the URI and is able to view the result of the parsed XML, she would successfully leak sensitive file content. However, the result of parsed XML is not always displayed back to the user, which is the case for the WordPress vulnerability described in this post. As we will see later, there are ways to cope with that.
This is the main idea and mechanism behind XXE (learn more in our rule database). Besides sensitive file disclosure, XXE can also have other impacts, such as Server-Side Request Forgery (to retrieve the content of external entities, a request has to be made, S5144), and Denial of Service (entities could reference other entities resulting in a possible exponential growth during substitution a.k.a. Billion laughs attack).
Exploitation
To exploit the described vulnerability it is necessary to understand if and how user-controlled data can reach the point where it gets parsed as XML as part of the $XMLstring variable in: wp-includes/ID3/getid3.lib.php
721 public static function XML2array($XMLstring) {
…
730 $XMLobject = simplexml_load_string($XMLstring, ‘SimpleXMLElement’, LIBXML_NOENT);
WordPress uses getID3 to ease extraction of this metadata when files are uploaded to its media library. Investigation of the getID3 library revealed that the string being parsed at that point is the iXML chunk of a wave audio file when its metadata gets analyzed.
wp-includes/ID3/module.audio-video.riff.php
426 if (isset($thisfile_riff_WAVE[‘iXML’][0][‘data’])) {
427 // requires functions simplexml_load_string and get_object_vars
428 if ($parsedXML = getid3_lib::XML2array($thisfile_riff_WAVE[‘iXML’][0][‘data’])) {
WordPress does allow uploading wave audio files, and extracts their metadata with the wp_read_audio_metadata() function (which relies on getID3).
Thus, by uploading a crafted wave file, malicious XML can be injected and parsed. A minimal file that has the necessary structure to be handled as wave and that contains an attack payload in the iXML chunk can be created with the following content:
RIFFXXXXWAVEBBBBiXML_OUR_PAYLOAD_
(BBBB being four bytes representing the length of the XML payload in little endian.)
Install the Patch and Upgrade!
As always, we recommend installing the latest patch and updating whenever possible.
You don’t want someone with nefarious intentions to access your files and destroy your website.
Believe us! We don’t want to see that happen to your website either.