Reporte de Errores

Cap铆tulo 28. Reporte de Errores

Hablando de la seguridad en PHP, hay dos caras en lo que se concierne al reporte de errores. Una es ben茅fica al incremento de la seguridad, la otra va en direcci贸n de su detrimento.

Una t谩ctica de ataque t铆pica involucra la acumulaci贸n de un perfil de datos del sistema aliment谩ndolo con datos inapropiados, y luego chequear los tipos de errores que son devueltos, y sus contextos. Esto permite que el cracker del sistema pueda adquirir informaci贸n del servidor, para as铆 determinar posibles debilidades. Por ejemplo, si un atacante ha recogido informaci贸n sobre una p谩gina creada a partir de los datos de un formulario, 茅l podr铆a intentar sobrescribir las variables, o modificarlas:

Ejemplo 28-1. Ataque a Variables con una p谩gina HTML personalizada

<form method="post" action="destino_del_ataque?username=badfoo&amp;password=badfoo">
<input type="hidden" name="username" value="badfoo" />
<input type="hidden" name="password" value="badfoo" />
</form>

Los errores de PHP que son devueltos normalmente pueden ser bastante 煤tiles para un desarrollador que est茅 tratando de depurar un script, indicando cosas como la funci贸n o archivo que fall贸, el archivo PHP y el n煤mero de l铆nea en donde ocurren los fallos. Toda esta es informaci贸n de la que puede sacarse provecho. No es extra帽o que un desarrollador php use show_source(), highlight_string(), o highlight_file() como medida de depuraci贸n, pero en un sitio en producci贸n, esta acci贸n puede exponer variables ocultas, sintaxis sin chequear, y otra informaci贸n peligrosa. Algo especialmente peligroso es ejecutar c贸digo que proviene de fuentes bien conocidas con gestores de depuraci贸n incorporados, o que usan t茅cnicas de depuraci贸n comunes. Si el atacante puede determinar qu茅 t茅cnica general est谩 usando, puede intentar un ataque de fuerza bruta sobre una p谩gina, enviando varias cadenas comunes de depuraci贸n:

Ejemplo 28-2. Explotaci贸n de variables comunes de depuraci贸n

<form method="post" action="destino_del_ataque?errors=Y&amp;showerrors=1&amp;debug=1">
<input type="hidden" name="errors" value="Y" />
<input type="hidden" name="showerrors" value="1" />
<input type="hidden" name="debug" value="1" />
</form>

Independientemente del m茅todo de gesti贸n de errores, la capacidad de conseguir que un sistema revele sus posibles estados de error representa un camino para darle informaci贸n al atacante.

Por ejemplo, el estilo mismo de un error de PHP gen茅rico indica que el sistema est谩 ejecutando PHP. Si el atacante estuviera viendo una p谩gina .html, y quisiera consultar qu茅 est谩 siendo usado para la generaci贸n de ella por detr谩s (en busca de debilidades conocidas en el sistema), podr铆a determinar que el sistema fue creado usando PHP aliment谩ndolo con informaci贸n equivocada.

Un error de funci贸n puede indicar si el sistema est谩 ejecutando un tipo particular de motor de base de datos, o dar pistas sobre c贸mo fue programada o dise帽ada una p谩gina web. Esto facilita posteriores investigaciones en determinados puertos abiertos de bases de datos, o en busca de fallos espec铆ficos o debilidades en una p谩gina web. Al entregar diferentes trozos de datos inv谩lidos al sistema, por ejemplo, un atacante puede determinar el orden de autenticaci贸n en un script, (a partir de los n煤meros de l铆nea de los errores) as铆 como averiguar sobre vulnerabilidades que pueden aprovecharse en diferentes puntos del script.

Un error del sistema de archivos o en general de PHP puede indicar qu茅 permisos tiene el servidor web, as铆 como la estructura y organizaci贸n de los archivos en el servidor web. Alg煤n c贸digo de gesti贸n de errores escrito por el desarrollador puede agravar este problema, llevando a la f谩cil explotaci贸n de informaci贸n hasta entonces "escondida".

Existen tres soluciones principales a este problema. La primera es revisar cuidadosamente todas las funciones, y tratar de compensar por la mayor铆a de errores encontrados. La segunda es deshabilitar el reporte de errores completamente del c贸digo que est谩 siendo ejecutado. La tercera es usar las funciones de gesti贸n de errores personalizables de PHP para crear su propio gestor de errores. Dependiendo de su pol铆tica de seguridad, puede encontrar que todas ellas pueden ser aplicables a su situaci贸n.

Una forma de detectar este problema por adelantado es hacer uso del reporte de errores propio de PHP (error_reporting()), para ayudarle a asegurar su c贸digo y encontrar uso de variables que pueda ser peligroso. Al probar su c贸digo, previamente a su entrega final, con E_ALL, puede encontrar r谩pidamente 谩reas en donde sus variables pueden estar abiertas a la manipulaci贸n y explotaci贸n en distintas formas. Una vez est茅 listo para liberar su c贸digo, es buena idea que deshabilite el reporte de errores por completo definiendo error_reporting() a 0, o desactive la impresi贸n de errores usando la opci贸n de php.ini display_errors, de modo que pueda aislar su c贸digo de ataques potenciales. Si elige la 煤ltima opci贸n, debe definir tambi茅n la ruta a su archivo de registro usando la directiva ini error_log, y habilitar log_errors.

Ejemplo 28-3. Detecci贸n de variables peligrosas con E_ALL

<?php
if ($nombre_usuario) {  // Variable no inicializada o chequeada antes de su uso
    
$login_correcto = 1;
}
if (
$login_correcto == 1) { // Si la condicion anterior falla, esta variable
                            // no se encuentra inicializada ni validada
                            // antes de su uso

    
readfile ("/informacion/altamente/confidencial/index.html");
}
?>