Evitar Inyección SQL (II)
Escrito por J.F. el Thursday, 6 de September del 2007 a las 22:00
Una vez visto en qué consiste la Inyección SQL y cuales pueden ser sus graves consecuencias, vamos a explicar algunos métodos para evitar dicho peligro, mediante la implementación de diferentes métodos. En general daré soluciones en concreto para PHP, pero son aplicables a otro tipo de lenguajes como ASP o JSP, aunque también trataré de dar alguna pequeña ayuda para los que usen éstos lenguajes. Vamos allá en principio, con las soluciones para PHP:
Aunque hay varias formas de protegerse contra la Inyección SQL en PHP, yo tan sólo voy a recomendar una serie de reglas generales a seguir:
Utiliza siempre las comillas simples (') para delimitar las variables que vayas a usar en una consulta a la base de datos. De esa manera la posibilidad de Inyección SQL se ve reducida de forma considerable:
-
SELECT usuario FROM indentificacion WHERE usuario= ' $usuario ';
Realiza las validaciones pertinentes para verificar el tipo que debe tener una variable. Ésto puedes realizarlo en el lado del cliente mediante el uso de Javascript, o bien por parte del servidor utilizando PHP. Aunque Javascript es recomendable, no puede ser 100% eficiente, por lo que es recomendable realizar siempre la validación al menos en el lado del servidor, y nunca depender unicamente de Javascript. Es decir, si en un campo esperas obtener un número, comprueba que sea un número, no confÃes en el "buen hacer" del usuario. Para ello puedes utiizar en PHP la función gettype(), que devuelve el tipo de la variable.
Evita el uso del operador asterisco (*), si deseas obtener 2 campos de una tabla, a pesar de que dicha tabla no contenga más que esos 2 campos trata de evitar el uso del asterisco(*). Imagina que posteriormente a la tabla sobre la que realizas una consulta se le añaden nuevos campos, estarÃas cargando información que no es encesaria, y dichos datos que no son utilizados para nada podrÃan ser obtenidos mediante una Inyección SQL. Además, seleccionar campos que no vas a utilizar posteriormente es aumentar el uso de memoria y de banda ancha del servidor, ralentizando la aplicación.
Puede ser que tengamos configurado nuestro servidor para que cambie las comillas de las variables pasadas, según leo en ProgramaciónWeb.net ejecutando el siguiente código podremos saber si nuestro servidor tiene activado dicho nivel de seguridad en función del mensaje mostrado en pantalla:
Si la prueba dice que somos vulnerables, quiere decir que la comilla simple(') no es cambiada por (\'). Para solucionar éste hecho proponen el siguiente script para "limpiar" las variables pasadas tanto por URL como por formulario:
inyeccion.php
-
<?
-
// Evitamos la inyeccion SQL
-
-
// Modificamos las variables pasadas por URL
-
foreach($_GET as $variable=>$valor){
-
}
-
// Modificamos las variables de formularios
-
foreach($_POST as $variable=>$valor){
-
}
-
?>
Luego tan sólo será necesario incluir el fichero en toda página que realicemos querys contra la base de datos:
-
<?
-
// Evitamos la inyeccion SQL
-
include 'inyeccion.php';
-
//
-
// Contenido de la página PHP
-
//
-
?>
Éste método es totalmente válido, aunque más tarde veremos otros métodos que yo al menos prefiero y son más eficaces.
Otro consejo, en éste caso de caracter general, es utilizar un único usuario para realizar todo tipo de consultas, y no utilizar como mucha gente hace el usuario root(administrador de la base de datos), ya que la que se puede armar es gorda.
La función que recomiendo, siempre que estemos programando en PHP y utilicemos la base de datos MySQL(es bastante común) es mysql_real_escape_string($parametro), que corrije la inserción de caracteres que puedan dar lugar a Inyección SQL, dejando "limpia" la variable que le pasamos. Aquà teneis un ejemplo tal y como indica la Wikipedia:
-
$query_result = mysql_query
-
(
-
"SELECT * FROM usuarios WHERE nombre = \""
-
.
-
mysql_real_escape_string($nombre_usuario)
-
.
-
"\""
-
);
Por último no debemos olvidar mencionar la función get_magic_quotes_gpc(), que se utiliza también para el filtrado de comillas. Según propone Mis-Algoritmos aquà teneis una función para filtrar una cadena antes de emplearle en la consulta contra la base de datos. La función en cuestión es la siguiente:
-
function sql_quote($value){
-
-
//check if this function exists
-
else//for PHP version <4.3.0 use addslashes
-
-
return $value;
-
}
La forma de utilizarla, según el propio autor comenta es la siguiente:
-
$password = sql_quote($_POST['password']);
Como vemos utiliza bien el entrecomillado en las variables, pero recordemos que debemos evitar el uso del asterisco (*) en medida de lo posible.
Dejando de lado PHP en concreto, también podemos utilizar la función replace de Visual Basic para eliminar caracteres no deseados. Un ejemplo de Maestros del Web.
-
SSQL= "SELECT count(*) FROM Usuarios WHERE Usuario = '" & ReplacetxtUsuario.Text, "’", "â€") & "’ AND password=’" & Replace(txtPassword.Text, "’", "â€") & "’"
Según comentan en Maestros del Web, otra solución definitiva serÃa crear un procedimiento almacenado, de modo que la inyección SQL queda anulada. Proponen el siguiente código:
CREATE Procedure Validar @usuario varchar(50), @password varchar(50)
ASIf (SELECT Count(*) FROM Usuarios WHERE Usuario=@Usuario and Password=@password)>0Return 1Return 0
Para Java, según la Wikipedia de nuevo, deberemos utilizar la clase PreparedStatement:
En lugar de
-
ResultSet rset = stmt.executeQuery("SELECT * FROM usuarios WHERE nombre = '" + nombreUsuario + "';");
deberemos utilizar:
-
pstmt.setString(1, nombreUsuario);
Con ésta serie de procedimientos doy por revisado algunos consejos generales y algunos métodos para evitar la Inyección de SQL en distintos tipos de lenguajes. Hay muchas más funciones y scripts por Internet que se adecuarán mejor o peor en función de tu situación especÃfica, asi que si crees que con lo visto en éste artÃculo no hay suficiente no dudes en seguir buscando por Internet. Para terminar, mañana veremos algunas herramientas y métodos para buscar vulnerabilidades en nuestro código SQL, además de algunos cuantos enlaces sobre el tema que nos vendrán de perlas.
Comentarios (7)
Categoria: General
- Añadir este post a
- Del.icio.us -
- Meneame -
- Digg -
- Webeame
Entradas relacionadas
Comentario de Angela
Realizado el Saturday, 7 de March del 2009 a las 19:55
Hola,
me ha sido de gran ayuda lo que publicaste sobre inyecciones de SQL. Muchas gracias por la explicacion, breve y clara.
Saludos.
Comentario de Darcon
Realizado el Tuesday, 17 de March del 2009 a las 21:10
Muuuchas gracias, me ahorraste mucho tiempo modificando archivo por archivo… el codigo de inyeccion.php es muy util.
Aunque me gustarÃa agregar que si ya tenemos un archivo que incluimos en todos los demás, como por ejemplo uno para conectar con la base de datos como conection.php…. podemos ingresar el código ahi y va a funcionar perfectamente.
Muchas Gracias!!!
Comentario de Alejandro
Realizado el Wednesday, 17 de June del 2009 a las 17:01
Clarisima la explicacion ya no ya…chevere muchas gracias
Comentario de Paulo Perez
Realizado el Saturday, 28 de November del 2009 a las 20:34
Oigan que bien!!…Mis felicitaciones, asi necesitamos pagina, claras y concreatas.
Comentario de adasd
Realizado el Saturday, 10 de April del 2010 a las 0:34
Comentario de Cristo
Realizado el Thursday, 2 de September del 2010 a las 17:16
Un gran artÃculo, sà señor, aunque esté escrito hace ya algún tiempillo. Me ha sido de gran ayuda para mejorar la seguridad de una web en la que estoy trabajando. Muchas gracias
Comentario de Cesar del Aguila
Realizado el Saturday, 21 de May del 2011 a las 2:32
Muy buena tu información, me ayudo a mejorar mi pagina web. A propósito, me costó un poco leer porque veo caracteres raros donde hay tildes, alguna idea de como arreglar esto?
