Actualización 17/04/2007: Al parecer el problema descrito ya no es válido en versiones recientes de PHP.
PHP incluye el soporte para expresiones regulares usando una sintáxis compatible con Perl (preg_match, preg_replace, preg_split
, etc) y también las expresiones con sintáxis POSIX extendido (ereg, eregi, ereg_replace, eregi_replace
, etc).
En esta oportunidad no hablaré de los problemas derivados del abuso o uso inadecuado de las expresiones regulares, sino un problema más específico para aquellos que usan las funciones POSIX-extendido de PHP, sobre el cual existe la siguiente advertencia en el manual de PHP:
Estas expresiones regulares no son seguras con material binario. Las Funciones PCRE lo son.
Bien, veamos un ejemplo en el que por usar este tipo de funciones, una aplicación puede llegar a sufrir problemas de XSS o Inyección de SQL (si es que sólo se usa este tipo de cosas para validar los parámetros):
php:
<?php
// re.php
header('Content-type: text/html; charset=utf-8');
if ( eregi('^[a-z0-9]{4}$', $_GET['key']) ) {
echo $_GET['key'];
} else {
echo 'Caracteres no válidos';
}
// ...
?>
La expresión regular definida para validar el parámetro key
supuestamente debería considerar sólo aquellos valores constituidos por cuatro letras y/o números, pero debido a que éstas funciones no son seguras con material binario, es posible saltar fácilmente esa validación añadiendo el caracter \0 (fin de cadena en C/C++).
Por ejemplo, para el siguiente valor de key
:
php:
<?php
header('Content-type: text/html; charset=utf-8');
$_GET['key'] = 'test' . chr(0) . '<script>alert("Texto no tomado en cuenta")</script>';
if ( eregi('^[a-z0-9]{4}$', $_GET['key']) ) {
echo $_GET['key'];
} else {
echo 'Caracteres no válidos';
}
// ...
?>
Se mostrará en el navegador lo siguiente:
code:
test?<script>alert("Texto no tomado en cuenta")</script>
Para conseguir este mismo resultado desde el navegador, sólo basta usar %00
en la URL para representar el caracter \0: key=test%00<foo>
.
Si están usando este tipo de funciones, ya están advertidos de los problemas que podrían tener si se les olvida la recomendación del manual de PHP.