¿Qué es Type Juggling?
Type Juggling (o “malabarismo de tipos”) es una característica de PHP que convierte automáticamente los tipos de datos durante las comparaciones o operaciones. Esto puede llevar a vulnerabilidades si no se maneja correctamente, especialmente cuando se usa el operador de comparación débil (==).
¿Por qué es peligroso?
El operador == en PHP no solo compara valores, sino que también intenta convertir los tipos de datos para que coincidan. Esto puede causar comportamientos inesperados, como que dos valores aparentemente diferentes sean considerados iguales.
Ejemplo de Type Juggling
En el código que proporcionaste, hay una vulnerabilidad de Type Juggling en la comparación de la contraseña:
$PASSWORD = 0e1231345134654654; // Esto es interpretado como 0 en notación científica
$contrasenia = md5($_POST['password']); // El hash MD5 de la contraseña
if ($contrasenia == $PASSWORD) { // Comparación débil (==)
echo "Bienvenido admin";
}¿Qué pasa aquí?
-
0e1231345134654654: En PHP, cualquier string que comience con0eseguido de números es interpretado como 0 en notación científica. Esto significa que0e1231345134654654es igual a0. -
Hash MD5: Si el hash MD5 de la contraseña también comienza con
0e(por ejemplo,0e462097431906509019562988736854), PHP lo interpretará como0. -
Comparación débil (
==): Como ambos valores son interpretados como0, la comparación$contrasenia == $PASSWORDserá verdadera, incluso si las contraseñas no coinciden.
¿Cómo explotar esto?
Un atacante puede enviar una contraseña cuyo hash MD5 comience con 0e, como:
- Contraseña:
240610708 - Hash MD5:
0e462097431906509019562988736854
Cuando el servidor compara 0e462097431906509019562988736854 con 0e1231345134654654, ambos son interpretados como 0, y el atacante obtiene acceso.
¿Cómo prevenir Type Juggling?
-
Usar comparación estricta (
===):
El operador===compara tanto el valor como el tipo de dato, evitando conversiones automáticas.if ($contrasenia === $PASSWORD) { // Comparación estricta echo "Bienvenido admin"; } -
Validar tipos de datos:
Asegúrate de que los datos sean del tipo esperado antes de compararlos. -
Evitar hashes que comiencen con
0e:
Almacena contraseñas de manera segura usando funciones comopassword_hash()ypassword_verify().
Código Corregido
Aquí está el código corregido para evitar la vulnerabilidad de Type Juggling:
<?php
$USER = "admin";
$PASSWORD = "contraseña_segura"; // Usa una contraseña segura y no un hash vulnerable
if (isset($_POST['usuario']) && isset($_POST['password'])) {
if ($_POST['usuario'] === $USER) { // Comparación estricta
if (password_verify($_POST['password'], $PASSWORD)) { // Verificación segura
echo "Bienvenido admin";
} else {
echo "ERROR: Password invalida";
}
} else {
echo "ERROR: usuario invalido";
}
}
?>Resumen
- Type Juggling: PHP convierte automáticamente los tipos de datos durante comparaciones, lo que puede llevar a vulnerabilidades.
- Vulnerabilidad: Usar
==para comparar valores puede permitir que un atacante explote hashes que comienzan con0e. - Prevención: Usa
===para comparaciones estrictas y funciones seguras comopassword_hash()ypassword_verify().
Diagrama de Type Juggling
sequenceDiagram participant Atacante participant Servidor Atacante->>Servidor: Envía contraseña con hash "0e..." Servidor->>Servidor: Compara con == (interpreta como 0) Servidor->>Atacante: Acceso concedido (vulnerabilidad explotada)
Consejo Final
Nunca uses comparaciones débiles (==) para valores sensibles como contraseñas. Siempre usa comparaciones estrictas (===) y funciones de hashing seguras.