Categories
PostgreSQL Recursos Software Libre

Presentaciones sobre PostgreSQL

Para los que quieran aprender un poco más sobre PostgreSQL, puede que las siguientes presentaciones sean de utilidad para quienes usen esta base de datos.

Fuente: http://lca2007.linux.org.au/Miniconfs/PostgreSQL

Categories
.NET ASP.NET Web

Protección de archivos con ASP.NET 2 e IIS 6

En ciertas ocasiones, es necesario controlar el acceso a los recursos o archivos de nuestra aplicación, bien sea por permitir sólo a usuarios registrados o con la intención de monitorear el número de descargas de éstos.

Todos los archivos relacionados a ASP.NET (aspx, asmx, ashx, asax, etc) son procesados por el runtime de ASP.NET y es por este motivo que se puede especificar que controlador HTTP se hará cargo de un determinado documento, a su vez también están disponibles los mecanismos de autenticación y autorización para éstos.

Categories
Seguridad XSS

¿Por qué algunos desarrolladores se complican la vida?

Esta semana definitivamente no me fue muy bien, primero porque dejé algunas cosas pendientes en el trabajo y segundo porque -como se habrán dado cuenta- no escribí mucho esta semana, pensaba hacerlo a partir del lunes, pero al ver la solución que le dieron al bug mostrado en la entrada anterior, no puedo dejar de comentar acerca de ésta 😉 .

Por alguna extraña razón, siguen permitiendo insertar HTML en la variable backURL, sólo que esta vez se basaron en algunos ejemplos básicos de la popular página que contiene diferentes vectores de ataques XSS, digo esto porque si usamos un ejemplo anterior que funcionaba, ahora ya no lo hace.

Paso a comentar dos ejemplos que funcionan en Internet Explorer (existen otros para otros navegadores):

  1. En la entrada anterior usamos <EMBED SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED> como valor para la variable backURL, con el cual era posible ejecutar javascript, pero si hacemos la prueba en este momento, este valor es descartado por contener la palabra embed. Una forma de saltar esa validación es insertar algo entre esa palabra, pero que ese algo todavía permita ejecutar javascript, si volvemos a nuestra página de referencia :), podemos ver que el caracter nulo (código ASCII 0) sirve para este propósito. Ejm.
  2. Este caso es aún más simple, porque hace uso de CSS -no estandar- para ejecutar javascript. Ejm

Esta lista podría ir creciendo dependiendo de las peculiaridades de cada navegador, lamentablemente los desarrolladores de esa página, usaron una solución compleja e ineficiente para un problema simple de resolver.

Si hay algo que me enseñaron desde mis inicios, es que no sirve corregir un problema en particular -mucho menos si éste depende de otras aplicaciones o componentes, se tiene que cortar el problema de raiz.

Categories
Seguridad XSS

XSS (Cross Site Scripting) en elpais.com

Hace cierto tiempo puse un quiz titulado "cuando los filtros no hacen lo que deberían", en el que preguntaba como explotar la casi nula validación de una variable. Pues bien, ese ejemplo hacía referencia al bug que existe en el sitio web del diario El País de España.

La URL afectada recibe como parámetro la variable backURL, que -supongo- sirve para redireccionar a esa URL una vez hecha la validación de los datos: http://www.elpais.com/clientes2/conectar1.html

Al parecer por la acción de un filtro, esta página envía un error (404) cuando backURL contiene en cualquier ubicación la palabra <script, pero por lo que se ve, los desarrolladores no se dieron cuenta de que existen otros vectores de ataque.

No tengo idea sobre el impacto de este bug en ese sitio, pero lo que está claro es que muchas empresas no le dan demasiada importancia a esto de la seguridad, ya que han pasado aproximadamente 3 meses desde que reporté este problema y hasta el momento ni lo han solucionado, ni he recibido respuesta alguna.

Categories
PHP Quiz Seguridad

Ejercicio de la Semana: Login de usuarios y actualización de datos

A partir de ahora, cada semana haré el intento de poner los quiz los días lunes o martes, así tendremos más tiempo para comentar estos pequeños ejercicios.

Esta vez, se trata de dos páginas: la primera que se encarga de realizar el login de los usuarios y la segunda se encarga de mostrar y actualizar el perfil del usuario que accede a la página.

php:

<?php
session_start();

/*
 session.php:
  Se encarga de validar los datos del usuario y
  que exista una sesión válida para acceder a user.php
*/

include_once './config.php';
include_once './db.php';

if ( !empty($_REQUEST['action']) ) {
        switch ($_REQUEST['action']) {
                case 'login':
                        if ( !empty($_SESSION['user']) ) {
                                header('Location: http://sitio/user.php');
                                exit();
                        }
                       
                        $username = $db->escape($_POST['user']);
                        $pass = md5($secret_key . $_POST['password']);
                       
                        if ( $user = $db->get_row("SELECT * FROM users WHERE user='$username' AND password='$pass'") ) {
                                session_regenerate_id();
                                $_SESSION['user'] = $user;
                                header('Location: http://sitio/user.php');
                                exit();
                        }
                        die('Usuario no válido');
                case 'logout':
                        // ...
        }
}

?>

php:

<?php
/*
 user.php:
   Se encarga de mostrar y actualizar el perfil de un usuario
*/

include_once './session.php';

if ( empty($_SESSION['user']) ) {
        header('Location: http://sitio/session.php');
        exit();
}

if ( !empty($_REQUEST['action']) ) {
        switch ($_REQUEST['action']) {
                case 'update-profile':
                       
                        // Limpiar los datos
                        $_POST['name'] = htmlspecialchars(strip_tags($_POST['name']), ENT_QUOTES, 'utf-8');
                        $_POST['email'] = preg_replace('/[^a-z0-9.@-]/i', '', $_POST['email']);   

                        // Escapar los valores
                        $user = $db->escape($_SESSION['user']->user);
                        $name = $db->escape($_POST['name']);
                        $email = $db->escape($_POST['email']);
                        $password = md5($secret_key . $_POST['password']);
                       
                        $sql = "UPDATE users SET name = '%s', email = '%s', password = '%s' WHERE user = '%s'";
                       
                        $db->query(sprintf($sql, $name, $email, $password, $user));
                       
                        break;
                case 'recover-password':
                        // ...
        }
}

?>

¿Existe algún bug en el código mostrado?

Actualización:

  1. Cambio de $_POST['user'] por $_SESSION['user']->user en user.php
  2. Cambio de ubicación de la comprobación de la variable user en la sesión

¿Todavía queda algún problema de seguridad?