Blind SQL Injection error-based no WordPress

Recentemente identificamos alguns plugins do WordPress com uma falha específica de SQL Injection, o Blind SQL Injection error-based. Segue alguns dos links publicados:

Qual o problema?

Essa falha explora o retorno do erro de uma query mal feita, através de tentativa e erro, validando um retorno correto e outro com problema, se quiser entender melhor temos um post inteiro a falar sobre o Error-based aqui.

Vale lembrar que essa falha só vai ocorrer se o modo debug estiver ativado.

Mas qual o motivo de estarmos encontrando tanto plugins com grande quantidade de downloads ativos com esse mesmo problema?

Existe algumas explicações:

O WordPress tenta da melhor forma escapar dados de entrada principalmente quando se é usado na clausula WHERE. Mas esquecem de escapar parâmetros que vêm depois, como ORDER BY Column e o posicionamento como ASC e DESC, ou uso do GROUP BY e LIMIT.

Todos esses itens podem ser explorados e precisam ser escapados.

Examplo:

$results = $wpdb->get_results("SELECT ID,post_title FROM {$wpdb->posts} WHERE id=$id ORDER BY $orderby limit $limit");
WHERE id=$id -> Falha de SQL Injection clássica.
ORDER BY $orderby limit $limit -> Explorada com Error-based Sql Injection nas variáveis $orderby e $limit.

E como se proteger?

Não devemos escapar apenas as clausulas WHERE, por segurança devemos escapar qualquer tipo de parâmetro que seja inserido na query de acordo com sua característica.

O WordPress tem alguns métodos que podem ajudar como sanitize_sql_orderby para os parâmetros do order by o intval() ou int() para parâmetros limit.

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

Outra dica boa é usar sempre valores pré definidos pelo sistema e nunca deixar que ele complete a query completamente, por exemplo usa um if baseado no dado de entrada para saber se ele vai usar ASC ou DESC no 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 ");

Author: lenonleite