0

WordPress 3.5: peligro de inyección SQL si ves “PHP Warning: Missing argument 2 for wpdb::prepare()”

codigo matrix hackeado

Nos avisa el bueno de Andrew Nacin de un grave error en sitios que han actualizado a WordPress 3.5 que, aunque no afecta a todos, es un potencial peligro de inyecciones SQL, así que no hay que tomarlo con ligereza.

El asunto es que hay usuarios que, debido a plugins o temas, están recibiendo un aviso bastante feo, este:

“PHP Warning: Missing argument 2 for wpdb::prepare().”

Pues bien, como se ha apuntado en los foros de soporte, esto es debido a que algo o alguien (un plugin) está usando incorrectamente la función $wpdb->prepare. Es un aviso de algo gordo, porque también indica un uso indebido de prepare(), y eso es un riesgo de seguridad.

No es un error de WordPress, más bien al revés, pues el equipo de desarrollo ha preferido que estos errores se muestren a que tengamos un agujero de seguridad por un plugin y no nos enteremos, así que en realidad está hecho por nuestro bien, mal que le pese a algún desarrollador que ahora tendrá que revisar su código.

Un ejemplo de esto sería esta línea de código en un plugin:

$wpdb->query( $wpdb->prepare( «UPDATE $wpdb->comments SET comment_parent=$parentID WHERE comment_ID=$commentID;» ) );

El problema es que no se ha usado la declaración de prepare correctamente, pues incluye las variables $parentID y $commentID directamente en el SQL. Para hacerlo bien se tendrían que usar “placeholders” y luego ya incluir las variables.

El ejemplo anterior es un código peligroso, ya que conlleva la posibilidad de que abra la puerta a un exploit de inyección SQL, o sea, el primer paso para hackear tu sitio web.

El código anterior se puede solucionar de este modo:

$wpdb->query( $wpdb->prepare( «UPDATE $wpdb->comments SET comment_parent=%d WHERE comment_ID=%d;», $parentID, $commentID ) );

Como ambos se supone que son integradores, se han reemplazado las variables en la declaración con el %d, y luego se ponen las variables al final de la declaración prepare(). Así es como se supone que se debe usar prepare. Si fueran cadenas entonces usas %s.

O sea, que si quieres arreglar momentáneamente el error tienes que encontrar la línea de código con el problema y corregirla. Con eso eliminas el exploit y el mensaje de aviso tan feo.

Por supuesto, lo anterior es un apaño temporal que solo te sirve a ti, no a toda la comunidad ni a WordPress en su conjunto, lo que hay que hacer en realidad si ves este error es lo siguiente:

Desactivar todos los plugins
Ir activando uno a uno hasta detectar el que provoca el error
Avisar al desarrollador indicándole el enlace del artículo de Andrew Nacin para que lo arregle y suba una versión segura

Lo mismo también puede pasar con un tema WordPress así que si tras hacer lo anterior sigue el error cambia de tema para comprobarlo.

La peor solución es ocultar los errores, aunque puedes hacerlo simplemente añadiendo estas líneas al fichero wp-config.php:

ini_set( ‘display_errors’, false );
error_reporting( 0 );

Un ejemplo de este error, lamentablemente, es el plugin Akismet, pues aunque acaban de actualizalo ahora mismo y soluciona el fallo deberían haber estado más pendientes, por la estrecha relación de Automattic con el desarrollo de WordPress.

 

Leave a reply