Un bug interesante en WordPress

El presente quiz está basado en un reciente bug de WordPress que fue corregido en la versión 2.0.6 de este CMS

php:
<?php

header('Content-type: text/plain; charset=utf-8;');

if ( empty($_POST['title']) ) {
        die('Parámetros no válidos');
}

// Conexión a la base de datos test
mysql_connect('localhost', 'root', '1234');
mysql_select_db('test');

// Escapar los valores
$title = mysql_real_escape_string($_POST['title']);

// Hacer la conversión si se envía el parámetro charset
if ( !empty($_POST['charset']) ) {
        // Verificar si la extensión mb_string está habilitada
        if ( function_exists('mb_convert_string') ) {
                $title = @mb_convert_encoding($title, 'UTF-8', $_POST['charset']);
        }
        // Verificar si la extensión iconv está habilitada
        elseif ( function_exists('iconv') ) {
                $title = @iconv($_POST['charset'], 'UTF-8', $title);
        }       
}

$sql = "SELECT * FROM wp_posts WHERE post_title = '$title'";

if ( $result = mysql_query($sql) ) {
        while ($row = mysql_fetch_assoc($result)) {
                print_r($row);
        }
       
        mysql_free_result($result);
}

/*
        Muestra el error intencionalmente
*/

if ( $error = mysql_error() ) {
        echo "MySQL: $error\nConsulta: $sql";
}

mysql_close();
?>

¿Dónde se encuentra el error? y ¿cómo explotarlo? (Si desean puedo colgar una página para que hagan las pruebas)

11 Replies to “Un bug interesante en WordPress”

  1. "creo" que el error por $_POST['title']

    cuando se realiza la consulta sql

    $title = $_POST['title']
    $sql = "SELECT * FROM wp_posts WHERE post_title = '$title'";

    podriamos agregar mas cosas a la consulta sql, realmente nose si se puede hacer eso voy a googlear un poco y ahi vere 😛

  2. Si miras el código, se aplica la funcion mysql_real_escape_string sobre el valor de $_POST['title'], así que el error no vá por ahí 🙂

  3. ¿y para que imprimes la consulta si hay error? ah no ser que lo uses solo en un server de pruebas, que supongo que no es la intencion del ejercicio.

  4. jdeveloper, se imprime la consulta para facilitar el trabajo de los que se tomen la molestia de probar ese código.

  5. No acabo de ver como, pero esta claro que title es modificado despues de mysql_real_escape_string() en caso de existir un charset.
    Así una \' podría modificar la \ por algun conjunto de caracteres y dejar el ' con que la injectsql seria posible.

  6. En efecto agusti, ese es el problema que presenta el código mostrado.

    La documentación de PHP dice lo siguiente sobre mysql_real_escape_string:

    Escapa todos los caracteres especiales en la cadena_no_escapada, tomando en cuenta el juego de caracteres actual de la conexión, de tal modo que sea seguro usarla con mysql_query()

    Como mencionabas, sólo habría que usar un charset en el que ' sea expresado en otra secuencia de caracteres, así se inutiliza completamente el uso de mysql_real_escape_string.

  7. Es (más) fácil ver un bug cuando te dicen que hay uno... de todas maneras y como norma escapar cadenas siempre es interesante hacerlo lo ultimo.

Comments are closed.