Vous êtes sur la page 1sur 3

Evita los ataques de inyeccin de SQL

Como evitar estos ataques


El principal problema de estos ataques es que si dejamos que el usuario del programa introduzca libremente caracteres sin control ninguno (mediante formularios, por ejemplo) puede llegar a aprovecharse de las comillas (simples y dobles con las que declaramos cadenas de texto o strings). Os voy a poner un pequeo ejemplo de una consulta SQL a la que le mandamos dos parmetros (independientemente del lenguaje, ya que cualquier lenguaje que use bases de datos SQL podra ser victima de estos ataques), que mediante el lenguaje que elijamos escribir tal cual le mandemos los parmetros.
#El usuario y la contrasea que mandamos son "Error", y se hara esta consulta: SELECT * FROM `Usuarios` WHERE `user`='Error' AND `pass`='Error' #Y en este ejemplo veremos el resultado de la inyeccin del SQL SELECT * FROM `Usuarios` WHERE `user`='Error' AND `pass`='' UNION SELECT * FROM `Usuarios` WHERE `id` = '1'

Por lo tanto la solucin genrica sera evitar que se pudieran introducir caracteres especiales (como comillas) sin haberlas transformado antes (por ejemplo, una comilla doble: " debera de transformarse en \" que as interpretar como texto la comilla y no como el carcter que cierra o abre el una texto en la consulta, pero segn el lenguaje se puede implementar de distintas formas y algunas son automticas y ms optimizadas.

PHP
En PHP tenemos varias formas de hacerlo, entre ellas para bases de datos MySQL tenemos la funcin mysql_real_escape_string, que aadiremos en las variables que introducimos en la consulta.
$respuesta=mysql_query("SELECT * FROM `Usuarios` WHERE `user`='".mysql_real_escape_string($name)."' AND `pass`='".mysql_real_escape_string($password)."'")

.NET
En .NET evitaremos la inyeccin en SQL Server (con C#) estableciendo el tipo de parmetro como literal con SqlDbType.VarChar.
SqlConnection con = new SqlConnection(_connectionString); SqlCommand cmd = new SqlCommand("SELECT * FROM Usuarios WHERE user=@user AND pass=@pass", con); /* Convertimos en literal estos parmetros, por lo que no podrn hacer la inyeccin */ cmd.Parameters.Add("@user", SqlDbType.VarChar, 32).Value = user; cmd.Parameters.Add("@pass", SqlDbType.VarChar, 64).Value = password;

O tambin podramos usar AddWithValue de una forma ligeramente similar a la anterior:


using( SqlConnection con = (acquire connection) ) { con. Open(); using( SqlCommand cmd = new SqlCommand("SELECT * FROM Usuarios WHERE user=@user AND pass=@pass", con) ) { /* Convertimos tambin en literales los parmetros */ cmd.Parameters.AddWithValue("@user", user); cmd.Parameters.AddWithValue("@pass", password); using( SqlDataReader rdr = cmd.ExecuteReader() ){ /* [...] */ } } }

Java
Ahora con Java lo que hacemos es similar a lo que hemos hecho con C# (en .NET), crear la consulta con los parmetros y posteriormente establecerlos (sustituirlos siendo ya estos un literal, que no producirn fallos de seguridad).
Connection con = (acquire Connection) PreparedStatement query = con.prepareStatement("SELECT * FROM Usuarios WHERE user=? AND pass=?"); query.setString(1, user); query.setString(2, password); ResultSet rset = query.executeQuery();

Perl
En este ejemplo de Perl usamos la caracterstica placeholder que al fin y al cabo es igual que con los dos ejemplos anteriores, agregando a la consulta los parmetros (con este mtodo se pone a punto las comillas para evitar las inyecciones SQL).
$query = $sql->prepare("SELECT * FROM Usuarios WHERE user=? AND pass=?"); $query->execute($user,$password);

Conclusin

Se pueden evitar estos ataques en muchos lenguajes distintos, e incluso hay lenguajes que por defecto hay que complicarse para que exista este fallo de seguridad, pero lo que tenemos que saber es que donde hay una consulta SQL puede haber una brecha de seguridad, por lo que recomiendo prestar un mnimo de atencin con estos ataques que estn tan de moda, y si alguno quiere comentar como hacerlo de otra forma o con otro lenguaje puede hacerlo en los comentarios, o comentar donde hay otros ejemplos.

Vous aimerez peut-être aussi