Disclosure: WordPress WPDB SQL Injection - Technical
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 technical vulnerability as well as how to mitigate it. There is another post which deals with the background and time-lines.
Simply upgrade to 4.8.3 and update any plugins that override
$wpdb (like HyperDB, LudicrousDB , etc). That should be enough to prevent these sorts of issues.
wpdb.php for clients.
There may be some firewall rules in the mean time that you could implement (such as blocking
%s and other
sprintf() values), but your mileage may vary.
To prevent this issue? Nothing, it’s been mitigated at the WP layer.
In general however, go through and remove all user input from the
$query side of
->prepare(). NEVER pass user input to the query side. Meaning, never do this (in any form):
$where = $wpdb->prepare(" WHERE foo = %s", $_GET['data']); $query = $wpdb->prepare("SELECT * FROM something $where LIMIT %d, %d", 1, 2);
This is known as “double-preparing” and is not a good design.
Also, don’t do this:
$where = "WHERE foo = '" . esc_sql($_GET['data']) . "'"; $query = $wpdb->prepare("SELECT * FROM something $where LIMIT %d, %d", 1, 2);
This is also conceptually unsafe.
Instead, build your queries and arguments separately, and then prepare in one shot:
$where = "WHERE foo = %s"; $args =
Truncated by Planet PHP, read more at the original (another 34330 bytes)