CONOCIMIENTO pertenece al mundo
Exención de responsabilidad : Este post es NO sobre la inyección de SQL.
FONDO
Recientemente, me encontré con una interesante pieza de código. El desarrollador había tratado de hacer todo lo posible intento de asegurar el acceso a la base de datos. El siguiente código se ejecuta cada vez que un nuevo usuario intenta registrar:
<?php
// Checking whether a user with the same username exists
$username = mysql_real_escape_string($_GET['username']);
$password = mysql_real_escape_string($_GET['password']);
$query = "SELECT *
FROM users
WHERE username='$username'";
$res = mysql_query($query, $database);
if($res) {
if(mysql_num_rows($res) > 0) {
// User exists, exit gracefully
.
.
}
else {
// If not, only then insert a new entry
$query = "INSERT INTO users(username, password)
VALUES ('$username','$password')";
.
.
}
}
Para comprobar la conexión, se utiliza el siguiente código:
<?php
$username = mysql_real_escape_string($_GET['username']);
$password = mysql_real_escape_string($_GET['password']);
$query = "SELECT username FROM users
WHERE username='$username'
AND password='$password' ";
$res = mysql_query($query, $database);
if($res) {
if(mysql_num_rows($res) > 0){
$row = mysql_fetch_assoc($res);
return $row['username'];
}
}
return Null;
¿Consideraciones de Seguridad?
- Parámetros de entrada del usuario filtro? - CONSULTAR
- Use comillas simples ( ') para mayor seguridad? - CONSULTAR
Fresco, lo que podría salir mal?
Pues bien, el atacante puede iniciar la sesión como cualquier usuario!
EL ATAQUE
Es crucial comprender algunos puntos antes de hablar sobre el ataque.
- En la realización de cadena de manipulación en SQL, se eliminan los espacios en blanco al final de la cadena. En otras palabras,
'vampire'
se trata de manera similar a'vampire '
. Esto es cierto para la mayoría de los casos, tales como cadenas en la cláusula WHERE o en las instrucciones INSERT. Por ejemplo., La siguiente consulta devolverá resultados con nombre de usuario como aún'vampire'
.SELECT * FROM users WHERE username='vampire ';
Existen excepciones, como la cláusula LIKE. Tenga en cuenta que este recorte de los espacios en blanco de cola se realiza principalmente durante la 'comparación de cadenas'. Esto es porque, internamente, almohadillas SQL una de las cadenas con espacios en blanco de modo que su longitud partidos antes de compararlos. - En cualquier consulta INSERT, SQL hace cumplir las limitaciones de longitud máxima en
varchar(n)
sólo por el uso de los primeros caracteres "n" de la cadena (en caso de que la longitud de la cuerda es más caracteres "n"). por ejemplo, si una columna en particular tiene una restricción de longitud de caracteres '5', luego insertando 'vampiro' dará lugar a la inserción de sólo "vampi '.
Ahora, vamos a configuración de una base de datos de pruebas para demostrar el ataque.
vampire@linux:~$ mysql -u root -p
mysql> CREATE DATABASE testing;
Query OK, 1 row affected (0.03 sec)
mysql> USE testing;
Database changed
Voy a crear una tabla
users
con dos columnas, username
y password
. Ambos de estos campos se limitará a 25 caracteres. A continuación, voy a insertarse una fila con el "vampiro" como nombre de usuario y 'my_password' como contraseña.mysql> CREATE TABLE users (
-> username varchar(25),
-> password varchar(25)
-> );
Query OK, 0 rows affected (0.09 sec)
mysql> INSERT INTO users
-> VALUES('vampire', 'my_password');
Query OK, 1 row affected (0.11 sec)
mysql> SELECT * FROM users;
+----------+-------------+
| username | password |
+----------+-------------+
| vampire | my_password |
+----------+-------------+
1 row in set (0.00 sec)
Para demostrar la guarnición de arrastre espacios en blanco, considere la siguiente consulta:
mysql> SELECT * FROM users
-> WHERE username='vampire ';
+----------+-------------+
| username | password |
+----------+-------------+
| vampire | my_password |
+----------+-------------+
1 row in set (0.00 sec)
Ahora, supongamos que un sitio web vulnerables utiliza el código PHP se mencionó anteriormente para manejar el registro de usuario e iniciar sesión. Para entrar en la cuenta de cualquier usuario (en este caso "vampiro"), todo lo que se necesita hacer es registrarse con un "vampiro [Muchos espacios en blanco] 1 'nombre de usuario y una contraseña aleatoria. El nombre de usuario elegido debe ser tal que los primeros 25 caracteres deben consistir sólo en 'vampiro' y espacios en blanco. Esto ayudará a pasar por la consulta que comprueba si un nombre de usuario particular, ya existe o no.
mysql> SELECT * FROM users
-> WHERE username='vampire 1';
Empty set (0.00 sec)
Tenga en cuenta que durante la ejecución de las consultas SELECT, SQL no acortar la cadena de 25 caracteres. Por lo tanto, la cadena completa se busca y se obtiene ningún resultado. A continuación, cuando se ejecuta una consulta INSERT, se insertan sólo los primeros 25 caracteres.
mysql> INSERT INTO users(username, password)
-> VALUES ('vampire 1', 'random_pass');
Query OK, 1 row affected, 1 warning (0.05 sec)
mysql> SELECT * FROM users
-> WHERE username='vampire';
+---------------------------+-------------+
| username | password |
+---------------------------+-------------+
| vampire | my_password |
| vampire | random_pass |
+---------------------------+-------------+
2 rows in set (0.00 sec)
Bien, ahora hay dos usuarios que serán devueltos en la búsqueda de "vampiro". Tenga en cuenta que el segundo nombre de usuario es en realidad 'vampiro' más 18 espacios en blanco al final. Ahora, si conectado con 'vampiro' y 'random_pass', cualquier consulta SELECT que busca por el nombre de usuario devolverá la primera y la entrada original. Esto permitirá que el atacante iniciar la sesión como el usuario original.
Este ataque ha sido probado con éxito en MySQL y SQLite. Creo que funciona en otros casos también.
DEFENSAS
Claramente, esta es una vulnerabilidad importante y necesita ser atendidos, mientras el desarrollo de software seguro. Algunas de las medidas de defensa que se pueden tomar son las siguientes:
- restricción UNIQUE debe añadirse a las columnas que se requieren / espera que sea único. En realidad, esto es una regla muy importante en relación con el desarrollo de software. Aunque el código intenta mantener la integridad, siempre definir sus datos correctamente. Con una restricción UNIQUE en 'nombre de usuario', insertando otra entrada no será posible. Tanto las cadenas serán detectados igual y la consulta INSERT fallará.
- Siempre es preferible el uso de "id" como la clave principal para la tabla de base de datos. Además, los datos deben ser rastreados por su identificación dentro del programa.
- Para mayor seguridad, también puede recortar manualmente los parámetros de entrada a una longitud particular (tal como se establece en la base de datos).
Fuente: https: //dhavalkapil.com/
CONOCIMIENTO pertenece al mundo
No hay comentarios:
Publicar un comentario