Disclosure: WordPress WPDB SQL Injection - Background
Today, a significant SQL-Injection vulnerability was fixed in WordPress 4.8.3. Before reading further, if you haven’t updated yet stop right now and update.
The foundations of this vulnerability was reported via Hacker-One on September 20th, 2017.
This post will detail the background on the vulnerability as well as why I publicly threatened to Fully Disclose. There is another post which deals with the technical vulnerability.
The Short Story
In short, the WordPress team released a “fix” in 4.8.2 that broke a LOT of sites. It was shown that the fix didn’t actually fix the root issue (but just a narrow subset of the potential exploits).
I reported a new vulnerability the day after the 4.8.2 was released. It was ignored for several weeks. Finally when I got the attention of the team, they wanted to fix a subset of the issue I reported.
It became clear to me that releasing a partial fix was worse than no fix (for many reasons). So I decided the only way to make the team realize the full extent was to Full Disclosure the issue. I started the process of going public by asking for Hosts and Plugin Developers to reach out to me so that we could coordinate the release.
During the planning steps of the FD, the WP team started constructive discussions again.
The 4.8.3 patch mitigates the extent of the issues I could find, and I believe is the second best way to fix the issue (with the first being a much more complex and time consuming change that still needs to happen).
Summary / Time-line
September 19th - WordPress releases 4.8.2 with a “fix”
This fix doesn’t actually fix the vulnerability, but breaks a metric ton of third-party code and sites in the progress (an estimated 1.2 million lines of code affected)
September 20th - I file a security vulnerability report and notify them the fix isn’t a fix and suggest they should revert and fix properly (with included details on how to fix)
- September 21st - WP closes my report saying “non documented functionality is non documented” (forgetting the 1.2 million LOC that uses said undocumented functionality). I replied a few times saying it was improper to close.
September 25th - I request public disclosure since ticket remains closed with no apparent resolution
1 hour later I get a response saying “Sorry for the delay and confusion, we’re still looking into this”
In this span, I posted 4 times adding information and requesting this be escalated, as well as addressing the root issue of the vulnerability.
October 16th - I announce my intention to go public on the 19th, barring any additional contact.
Same day I receive a reply “I’ll get you an update tomorrow”
October 17th - WP replies with a full history of the vulnerability, but still no indication of anything that I said, nor any indication that they would fix anything. In fact, their exact reply for next steps was:
Publishing the details of the issue will be the next step. Once that’s done, #41925 can be reopened and work can be done to add in support for numbered placeholders if there are people that want to do so and if it can be done without re-creating any vulnerabilities.
Note that this doesn’t actually admit to any of the issues found so far.
October 18th - I reply talking about the fact that the vulnerability still wasn’t fixed, and demonstrating a black-and-white proof-of-concept as to the break.
WP replies stating that they are “triaging” the bug (a month into this ordeal) and will fix the
meta.php
issue…So far, they haven’t admitted root issue (that their prepare system is poorly designed and must be fixed conceptually), but only the surface level repercussions of it (and even then only a few of them).
Also receive a patch to remove the “double prepare” from
meta.php
October 20th - Receive a reply saying “we’re working on it” and discussing some details of the fix. Specifically that they are going to try to implement something I had suggested earlier (using a “comment marker” to indicate if a string has been through
WPDB::prepare()
before).It’s worth noting that the reply indicated some hesitance to fix this because:
Regarding broken plugins – I’m sure there are plugins that double prepare things as well. Goi
Truncated by Planet PHP, read more at the original (another 7042 bytes)