Blind SQL Injection error-based on WordPress

We recently identified some WordPress plugins with a specific SQL Injection flaw, the error-based Blind SQL Injection. Here are some of the published links:

What the problem?

This vulnerability exploits the error return of a bad query, through trial and error, validating a correct return and validating another with a problem, if you want to understand better we have an entire post talking about Error-based here.

Remember that this vulnerability will only happen if the debug mode is enabled.

But why are we finding so many plugins with a large number of active downloads with this same problem?

There are a few explanations:

Developers try their best to escape input data especially when it is used in the WHERE clause. But they forget to escape parameters that come later, like ORDER BY Column and positioning like ASC and DESC, or use of GROUP BY and LIMIT.

All of these items can be explored and need to be escaped.

Examplo:

$results = $wpdb->get_results("SELECT ID,post_title FROM {$wpdb->posts} WHERE id=$id ORDER BY $orderby limit $limit");
WHERE id=$id -> Classic SQL Injection failure.
ORDER BY $orderby limit $limit -> Explored with Error-based Sql Injection in the variables $ orderby and $ limit.




And how to protect yourself?

We must not escape only the WHERE clauses, for safety we must escape any type of parameter that is inserted in the query according to its characteristic.

WordPress has some methods that can help like sanitize_sql_orderby for order by o intval () parameters or int () for limit parameters.

Usar esc_attr ou esc_html não irá resolver esse tipo de solução, para cada problema existe uma solução específica.

Another good tip is to always use pre-defined values by the system and never let it complete the query completely, for example use an if based on the input data to know if it will use ASC or DESC in the order by.

$orderBy = ‘ASC’;

if($var != ‘ASC’){

$orderBy = ‘DESC’;

}

$wpdb->get_results("SELECT ID,post_title FROM {$wpdb->posts} WHERE id=1 ORDER BY ID $orderBy ");

So the most important is to use the sanitize correctly for the situation.

Author: lenonleite