Esta vulnerabilidad puede ser evitada por el programador, comprobando y manipulando la cadena entrante, para poder detectar cualquier abuso en el uso de la información entrante. Lo que se puede entender a partir de esto es que este tipo de errores se generan por la falta de conocimientos del programador, por el descuido en la programación, o en las malas costumbres de programación.
Veamos como se da este proceso de ataque y mala programación en un script PHP haciendo interfaz con MySQL y utilizando un form HTML.
El primer contacto del usuario con la aplicación es la interfaz HTML y en concreto la FORM de éste. Se pueden agregar ciertas restricciones a la entrada de tal forma que pareciera segura la aplicación:
< form action=”process.php” method=”POST” >
Seleccione el color:
< select name=”color” >
< option value=”red” > rojo< /option >
< option value=”verde” > verde< /option >
< option value=”azul” > azul< /option >
< /select >
< input type=”submit” / >
< /form >
Sin embargo, sabemos que no sería suficiente con esta restricción, pues es posible ingresar directamente los valores al script process.php sin la necesidad de limitarnos a las opciones antes vistas.
process.php?color=morado
hasta este punto llega el ataque XSS, donde se introduce código mailicioso dentro de las entradas que no se suponen que puedan ser distintas, pero ahora veamos como se da esto en una entrada donde la cadena será usada en una sentencia SQL.
Supongamos el siguiente script PHP:
Si el usuario es una perosona bien intencionada introducirá su usuario y si password sin que pase nada. La sentencia SQL sería:
SELECT count(*)
FROM users
WHERE username = ‘juan’
AND password=’eselmejor’”;
y Juan accesará a su cuenta sin mayor problema.
Pero el pasado script es vulnerable, pues no comprueba la entrada que llega del método POST. Supongamos que el atacante sabe que -- es el comando SQL para comentario, entonces, todo lo que se introduzca después de los dos guiones no será reconocido por el SQL y se evita automáticamente la comprobación del password, dando acceso total el invasor. Con la siguiente entrada de usuario será:
Juan’--
Se ejecutará la siguiente sentncia:
SELECT count(*)
FROM users
WHERE username = ‘juan’--‘
AND password=’eselmejor’”;
Pero como AND password=… es un comentario no será tomado en cuenta será ejecutado:
SELECT count(*)
FROM users
WHERE username = ‘juan’
Entrando a la cuenta de Juan sin permiso y evitando la comprobación de password.
Veamos que otros posibles abusos pueden ser cometidos con Inyección SQL. Hace búsqueda de fuerza bruta del password del un usuario con una cierta dirección de correo electrónico:
SELECT email, passwd, login_id, full_name
FROM members
WHERE email = 'bob@example.com' AND passwd = 'hello123';
Elimina una tabla de la base de datos:
SELECT email, passwd, login_id, full_name
FROM members
WHERE email = 'x'; DROP TABLE members; --'; -- Boom!
Crea una nueva cuenta papra poder acceder a la base de datos in mayor problema:
SELECT email, passwd, login_id, full_name
FROM members
WHERE email = 'x';
INSERT INTO members ('email','passwd','login_id','full_name')
VALUES ('steve@unixwiz.net','hello','steve','Steve Friedl');--';
Y así se podría continuar hasta que la imaginación lo permita. Pero ahora surge la preunta: ¿Cómo se debió haber programado el script PHP desde el principio para poder evitar estos ataques?
Se debe comprobar la cadena entrante de la siguiente forma:
prepare(‘ SELECT count(*)
FROM users
WHERE username =:username’
AND password=:hash’);
$sql->bindParam( ‘:username’,
$clean[‘username’],
PDO_PARAM_STRING,
32);
$sql->bindParam( ‘:hash’,
$hash($_POST[‘password’]),
PDO_PARAM_STRING,
32);
.......
?>
Referencia:
Rasmus Lerdorf, Kevin Tatroe & Meter MacIntyre. Programming PHP, Segunda edición abril 2006, Estados Unidos ed.: O’Reilly Media.
http://unixwiz.net/techtips/sql-injection.html
http://es.wikipedia.org/wiki/Inyecci%C3%B3n_SQL
No hay comentarios:
Publicar un comentario