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 16-11. Ataque a Variables con una página HTML
personalizada <form method="post" action="destino_del_ataque?username=badfoo&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 16-12. Explotación de variables comunes de
depuración <form method="post" action="destino_del_ataque?errors=Y&showerrors=1&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, usando E_NONE
puede aislarlo de posibles intentos por adquirir
información útil para un atacante.
Ejemplo 16-13. 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"); } ?>
|
|