Tips para evitar SQL Injection

En un gran porcentaje, la mayoría de nuestras aplicaciones necesitan acceder a las bases de datos para realizar consultas, actualizaciones e incluso eliminaciones de nuestros registros… El problema es cuando alguien desde fuera intenta hacer esas tareas por nosotros 😉

Voy a proponeros algunos tips a la hora de tratar los valores ajenos a nosotros desde el lado del servidor, para evitar este tipo de catástrofes. Por otro lado, cualquier tip adicional será bienvenido 😀

Convierte siempre el valor a su tipo correspondiente

Si por ejemplo estamos esperando un valor de tipo numérico, deberíamos intentar parsear este valor a dicho tipo para asegurarnos de que no incluye texto adicional:


var id = Request.QueryString["id"];

int result;

if (Int32.TryParse(id, out result))
    //Do things

Parametrizar las consultas SQL

Un error muy común es hacer uso de los valores que nos llegan sin especificar ningún tipo para el mismo. Algo parecido a esto:

var id = Request.QueryString["id"];
var query = "SELECT * FROM HOUSES WHERE ID=" + id;

Para evitarlo, podemos parametrizar las sentencias SQL y poder especificar de esta manera el tipo que estamos esperando para cada parámetro.


var objConnection = new OleDbConnection(strDbConnectionString);

objConnection.Open();

const string query = "SELECT * FROM HOUSES WHERE ID=?";

var objCommand = new OleDbCommand(query, objConnection);
var id = new OleDbParameter("@idParam", OleDbType.Integer) { Value = id};
objCommand.Parameters.Add(id);

var objReader = objCommand.ExecuteReader();;

Usar una cuenta con permisos restringidos a la base de datos

Otro dato importante a tener muy en cuenta es asegurarnos de que la cuenta de usuario utilizada por nuestra aplicación tiene los permisos necesarios para poder acceder y/o modificar unos datos concretos pero también que sea lo suficiente restrictiva para no alterar otro tipo de datos.

No mostrar al usuario la información de error generada por la base de datos

En muchos casos los mensajes de error pueden ser lo suficientemente descriptivos como para que el usuario se percate de información acerca de la estructura de la base de datos.

Rechazar las peticiones con caractéres sospechosos

Carácter especial Significado SQL
; Delimitador de consultas.
Carácter delimitador de cadena de datos.
Comentario.
/* */ Delimitadores de comentario. El texto entre /* y */ no es evaluado.
xp_ Se utiliza en el inicio del nombre de procedimientos almacenados extendidos de catálogo, como xp_cmdshell.

Espero que sea de utilidad 🙂

¡Saludos!

9 comentarios en “Tips para evitar SQL Injection”

  1. @PyxisPyro, el uso de Procedimientos Almacenados sobre todo en EF, es poco recomendable ya que debes abstraerte de la base de datos, las recomendaciones de este post no son utilizar SP de forma masiva.

  2. @Juan, ¿porqué dices que los SPs no son recomendables? hasta donde yo entiendo de EF (que es más bien poco), existe una posibilidad de utilizar EF+SPs, es más trabajosa, pero los commands+params pueden ahorrarte más de un susto en este escenario.
    Ojo que esto saca 2 temas pa debatir:

    – realmente necesitamos abstraernos de una base de datos? cuantas veces hemos cambiado Oracle por SQL, o Informix por DB2 en un proyecto?
    – usar SPs o no usar SPs. Ahora la tendencia vuelve a ser no utilizar SPs, pero como esto cambia cada vuelta de reloj 😀

    Ahh y @Gise, nice article XD

  3. @Bruno, en base a esas ideas, por que no usar Entity to Sql, se supone que EF
    se diseña entre otras cosas para permitir abstraerse de la base de datos que utilizas,
    la sencillez del diseño de consultas en EF con la utilización de parámetros hace que solo en casos
    determinados donde quieras sacar verdadero partido a Sql sea necesario el uso de SP, no hay que olvidar
    que el uso de SP supone un coste mayor en cuanto al mantenimiento del SP y del código que lo utiliza y crea dependencias sobre la base de datos, si en algun momento quieres migrar esto tendra un alto coste, los SP también son fruto de problemas, tienes que mantener sincronizados el código de sql y de tu aplicación y es fácil olvidarse de cambiar el tamaño o el nombre de cualquier parámetro en los dos sitios.

    No sere yo el que desaconseje el uso de SP, de hecho mi aplicación actual usa de forma masiva
    SP, tengo mas de 400, se que alguno pondria el grito en el cielo, pero en mi caso comence el proyecto hace ya varios años y EF no era una opción. Entiendo que el artículo de Gisela se refiere a parametrizar consultas para evitar SQL Injection, no al consejo de hacer todo con SP, por eso deje la nota en post.

    Es un tema muy interesante para discutir y estoy deacuerdo que muchas decisiones se toman por moda, aunque insisto, si mi aplicación utilizara EF, intentaria reducir mis SP al máximo ya que son muy pocas las situaciones donde la ganancia por rendimiento merezca la pena, y pienso que es importante que todo tu código de acceso a datos se encuentre en una sola capa y sea facil de mantener, algo que muchas veces no tenemos en cuenta.

    Un saludo.

  4. No voy a entrar en si usar SPs o no… sólo que, que si el motivo de usarlos es OBTENER MAYOR SEGURIDAD, estamos un error. Las consultas parametizadas ofrecen el mismo nivel de seguridad. Asi, pues usar SPs o no puede dar (ha dado y dará :p) para muchas discusiones, pero no creo que la seguridad tenga nada que decir al respecto.

    @Bruno
    Abstraernos de la BBDD? No creo que la respuesta sea abstraernos para cambiar de SQL Server a Oracle. Yo *quiero* abstraerme de la BBDD, no porque quiera cambiarla, sinó porque NO quiero saber nada de ella: quiero saber de mi modelo de dominio, no de mi modelo de datos. Usar una BBDD és una opción tecnológica que debería condicionarme lo más mínimo. Ahí es donde entran herramientas como EF. 🙂

    Saludos!

  5. ¡Buenas a todos!

    En primer lugar, muchas gracias a todos por vuestros comentarios. Da gusto cuando un tema da de qué hablar 🙂

    En primer lugar, como bien comenta Eduard, gracias a las consultas parametrizadas conseguimos del mismo modo que con los SPs evitar los ataques de inyección de SQL que era el objetivo principal de este post.

    Por otro lado, me gustaría añadir que no soy muy partidaria del uso de SPs. En mi opinión estos deberían usarse lo mínimo posible ya que soy creyente de que la lógica de negocio debería residir en la aplicación y no en la base de datos.

    Jesús Bosch, en cuanto al carácter < como bien dices sería necesario omitirlo o denegarlo por temas de inyección de scripts, de lo que me gustaría crear un post sobre algunos tips al respecto también 🙂 Creo que este tipo de post son necesarios ya que me he dado cuenta de que no todo el mundo tiene en consideración este tipo de cosas 🙁 ¡Saludos!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *