¿Por qué sucede esto?
Se debe a que PHP tiene escritura suelta . Echa un vistazo a este ejemplo:
$x = "1e6";
echo strlen($x); // 3
echo $x * 1; // 1 000 000
En la segunda línea, se supone que $x
es una cadena, y como tal obviamente tiene una longitud de tres caracteres. En la tercera línea, $x
se interpreta como un número entero, o 1 000 000 en este caso.
¿Es un problema?
Esto definitivamente puede causar errores, y cada error es una vulnerabilidad de seguridad potencial. Pero por sí solo, no hace que su aplicación sea vulnerable de forma predeterminada. Pero intentemos imaginar un escenario en el que podría causar un problema.
Digamos que un foro tiene grupos numerados a los que los usuarios pueden unirse libremente, pero los primeros 10 grupos (de 0 a 9) están reservados para los administradores. El código para joingroup.php
tiene este aspecto:
$group = $_POST['group'];
if(strlen($group) > 1 || $isadmin) {
join_group($group, $uid);
}
else {
// Fail.
}
Puedes ingresar a un grupo de administradores sin ser un administrador al publicar, por ejemplo. 0.3e1
, que tiene una longitud de cadena 5 pero se evalúa como 3. Lo sé, es un ejemplo tonto. El punto que quiero señalar es que si confía en strlen()
(o cualquier otra cosa que trate la entrada como una cadena) para validar los datos numéricos, podría ser vulnerable.
La publicación de 3.0
o 3
también pasará por alto esta comprobación. Para obtener más información sobre cómo PHP convierte implícitamente cadenas en números, consulte el manual .
¿Cómo debo lidiar con esto en PHP?
Valide la entrada del usuario. Compruebe que realmente obtiene un número entero cuando espera obtener un número entero:
if(!ctype_digit($group)) {
// Fail.
}
También es una buena idea tratar siempre algo que debe ser un entero como un entero y no como una cadena:
$group = (int) $_POST['group']
if($group > 9 || $isadmin) {
// ...
¿Se está filtrando información del sistema?
Al parecer, esto puede revelar el valor entero máximo. Quizás alguien podría deducir que estás usando PHP a partir de esto, pero probablemente ya hay muchas otras formas de hacerlo. El valor máximo depende de la plataforma, por lo que podría utilizarse para la toma de huellas dactilares. Pero en la práctica, probablemente se usan 32 bits en un sistema de 32 bits y 64 bits en un sistema de 64 bits. Esa es la única información que está filtrando.