Prevenir MySQL Injection
Muchas veces es difícil darse cuenta como el ingreso de información desde un formulario, puede causar daños o robo de información a nuestra Base de Datos.
De esto se trata este artículo, prevenir los ataques a nuestro sitio web mediante MySQL Injection.
Basado en mi formación profesional y en los 30 años de experiencia con el manejo de Base de Datos en centros de cómputos y en servidores web, es que les voy a mostrar esta serie de ejemplos:
$usuario = $_POST['usuario'];
$clave = $_POST['clave'];
$query = "SELECT * FROM usuarios WHERE usuario='$usuario' AND clave='$clave'";
A primera vista, el código PHP escrito arriba es correcto, funciona bien y aparece en cientos de tutoriales en Internet.
El problema es que ese código es vulnerable y si lo hemos usado así estamos expuestos a perdida o robo de información.
Veamos como se traslada la información si un usuario ingresa su nombre y clave en nuestro formulario. Para el ejemplo, suponemos que el nombre es: "carlos" y la clave es "1234567" :
SELECT * FROM usuarios WHERE usuario='carlos' AND clave='1234567'";
Eso está perfecto, pero que pasa si el usuario en lugar de ingresar "carlos" y "1234567", ingresa lo siguiente:
usuario = admin' #
sin importar lo que ingrese en la clave.
Estos nuevos datos de usuario y clave nos producen un gran problema. Primero veamos como se sustituyen en el query:
SELECT * FROM usuarios WHERE usuario='admin' #' AND clave=''";
Ahora sí se puede ver realmente el problema. Ya que el simbolo "#" le dice a PHP que lo que viene a continuación es un comentario. Entonces el query queda reducido a esto:
SELECT * FROM usuarios WHERE usuario='admin'
Y el resultado es mostrar todos los datos del usuario "admin".
En este punto el usuario que ingresó la información tiene todos los datos de nuestro administrador. Interesante verdad?, bueno esto es lo que debemos prevenir para ser vulnerables en Internet.
Si estás usando un código similar al mostrado arriba y aún no has tenido robo de información (o aún no lo sabes), es porque tienes mucha suerte.
Veamos ahora otro ejemplo con pérdida de datos, que se puede dar cuando un usuario se da de baja de nuestro registros.
El código por lo general suele ser el siguiente:
$usuario = $_POST['usuario'];
$clave = $_POST['clave'];
$query = "DELETE FROM usuarios WHERE usuario='$usuario' AND clave='$clave'";
De nuevo, esto se ve bien y aparenta no tener problemas, pero es causa de pérdida de datos.
Veamos que pasa si un usuario ingresa lo siguiente:
usuario = anything' OR 1=1 #
sin importar lo que ingrese en la clave.
MySQL lo va a interpretar de la siguiente forma:
DELETE FROM usuarios WHERE usuario='anything' OR 1=1 #' AND clave....
Ouch!!! Esto siempre es true para MySQL y por lo tanto se va a borrar la tabla de usuarios.
La pregunta es: que vas a hacer frente a este tipo de ataques?
Lo primero que debemos hacer es evitar que nos ingreses caracteres especiales o "magic quotes" en los campos de input de nuestros formularios PHP. Limpiar todo el código NO esperado cuando trasladamos la información de PHP a MySQL. Una forma elegante que se puede implementar facilmente es usando la siguiente función:
<?php
function mysql_fix_string($string) {
if (get_magic_quotes_gpc()) $string=stripslashes($string);
return mysql_real_scape_string($string);
}
?>
la funcion get_magic_quotes devuelve TRUE si los magic quotes están activos. En este caso, se borran todos los slash que se ingresaron en el campo de input.
El siguiente es un ejemplo del uso de esta función:
<?php
$usuario = mysql_fix_string($_POST['usuario']);
$clave = mysql_fix_string($_POST['clave']);
$query = "SELECT * FROM usuarios WHERE usuario='$usuario' AND clave='$clave'";
function mysql_fix_string($string) {
if (get_magic_quotes_gpc()) $string=stripslashes($string);
return mysql_real_scape_string($string);
}
?>




Lista de comentarios
Comentar el artículo