Bueno, entonces una persona diestra en SQL Injection es un peligro para mi web site... claro que si! El SQL Injection no solo puede hacer maldades, sino también eliminar información importante o incluso la tabla entera.
Como puede hacerse esto? bueno acá hay un ejemplo muy bueno de que es esto.
como podemos obtener acceso a un sitio sin validar, con una simple sintaxis de SQL... por donde lo mires, apuesto a que la gran mayoría de ustedes queridos lectores no había tomado en cuenta que algo así se podía hacer.
Interesante no! A veces podemos confiarnos de muchas cosas, porque simplemente... a mi no me va a pasar, pero siempre existen personas con intenciones para nada honorables, las cuales estan esperando el menor descuido de un webmaster, para cometer sus fechorías, pero no solo ese tipo hay. Imaginemos este otro ejemplo.Usuario: ' OR 1 = 1; /*
Password: */--
Tenemos en nuestro sitio una consulta de este tipo:
Si el usuario escribe su nombre, digamos "Juan de los palotes", nada anormal sucedería, la aplicación generaría una sentencia SQL similar a la siguiente, que es perfectamente correcta, en donde se seleccionaría al usuario "Juan de los palotes":consulta := "SELECT * FROM usuarios WHERE nombre = '" + nombreUsuario + "';"
Pero si un usuario malintencionado escribe como nombre de usuario:SELECT * FROM usuarios WHERE nombre = 'Juan de los palotes';
"Juan de los palotesLa base de datos ejecutaría la consulta en orden, seleccionaría el usuario 'Juan de los palotes', borraría la tabla 'usuarios' y seleccionaría datos que quizá no están disponibles para los usuarios web comunes. En resumen, cualquier dato de la base de datos está disponible para ser leído o modificado por un usuario malintencionado.'; DROP TABLE usuarios; SELECT * FROM datos WHERE '-' = '-", se generaría la siguiente consulta SQL, (el color verde es lo que pretende el programador, el azul es el dato, y el rojo, el código SQL inyectado):
SELECT * FROM usuarios WHERE nombre = 'Juan de los palotes'; DROP TABLE usuarios; SELECT * FROM datos WHERE '-' = '-';
Ahi hay otro ejemplo de lo peligroso que puede ser SQL Injection:
Queremos sacar el password de una tabla.. pero.. ¿como?
Hay una instrucción en SQL llamada UNION, que sirve para obtener información de 2 tablas, o..
Bueno.. UNION necesita algunos requisitos.
- Necesitas meter la misma cantidad de valores que tiene la tabla.
- Tener un informe de los errores que provocaremos en la instrucción
Bien ahora empecemos, La instrucción a modificar es la siguiente:
SELECT password FROM usuarios WHERE user = '$us'como ejemplo, si colocamos de usuario: zanahoria
la instrucción que llega seria:
SELECT password FROM usuarios WHERE user = 'zanahoria'Otra vez necesitamos creatividad regresemos al UNION.
UNION necesita que el numero de columnas sea igual, sino sacara un error y exactamente, lo que necesitamos es un error, que nos diga cuando estamos mal, para saber cuando estamos bien, el UNION se usa de esta forma:
Usuario: ' AND 0 UNION SELECT 1 AND 'l'='para lo cual SQL nos respondera:
SELECT password FROM usuarios WHERE user = '' AND 0 UNION SELECT 1 AND 'l'=''
Continuando por el mismo camino, podemos hacer que nos regrese un error, al tratar de UNIR un campo de tipo INT (osea que guarda numeros) a un CHAR (guarda letras)The used SELECT statements have a different number of columns: SELECT password FROM usuarios WHERE user = '' AND 0 UNION SELECT 1 AND 'l'=''
Quedaria algo asi:
' UNION SELECT MIN(Password),2,3,4,5 FROM usuarios WHERE user = 'zanahoriala sentencia seria esta:
SELECT password FROM usuarios WHERE user = '' UNION SELECT MIN(Password),2,3,4,5 FROM usuarios WHERE user = 'zanahoria'que nos da como error:
donde el password es naranjaSyntax error converting the varchar value 'naranja' to a column of data type int.
Ven que peligroso es esto, pero por dicha hay muchas estrategias que podemos utilizar para evitar este tipo de cosas, como por ejemplo:
$query_result = mysql_query
(
"SELECT * FROM usuarios WHERE nombre = \""
.
mysql_real_escape_string($nombre_usuario)
.
"\""
);Este codigo en general lo que hace es a la variable nombre usuario, la hace pasar por un filtro, el cual es claramente una funcion PHP, la cual hace una llamada a las librerias de MySQL, las cuales validan las empresion eliminando "backslashes", y algunos caracteres como " \x00, \n, \r, \, ', " y \x1a".
Esto con el fin de frustrar una posible SQL Injection.
O tambien podemos utilizar un codigo de este tipo:
Esta funcion va a validar las expreciones que se le envien como parametros, ademas de pasar un filtro elif (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "")
{
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
$theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);
switch ($theType) {
case "text":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "long":
case "int":
$theValue = ($theValue != "") ? intval($theValue) : "NULL";
break;
case "double":
$theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
break;
case "date":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "defined":
$theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
break;
}
return $theValue;
}
}
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;luego de esto el valor sera clasificado, para su analisis, y por ultimo
//Pregunta si las magic_quotes estan habilitadas, si es asi, entonces utilizar stripslashes para eliminarlas
$theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue); //En caso de que exista la funcion "mysql_real_escape_string", utiliza esa, pero si no utiliza "mysql_escape_string", dependiendo de la version de PHP.
$LoginRS__query=sprintf("SELECT user, pwrd FROM usuarios WHERE user='%s' AND pwrd='%s'",Bueno creo que esto es todo por hoy, espero tener mas temas dentro de poco, saludos.
GetSQLValueString($loginUsername, "-1"), GetSQLValueString($password, "password"));
//Tratara de validar el texto introducido, en la funcion anterior
$LoginRS = mysql_query($LoginRS__query, $sql_conection) or die(mysql_error());
//Al final ejecutara el query a como venga, luego de los filtros.
No hay comentarios:
Publicar un comentario