Es común en nuestros ASP usar lo que el usuario pone en un formulario para
montar una consulta SQL (contra una base de datos Access o SQL Server). Por ejemplo, una
tipica pagina de validacion de usuario y contraseña tendria esta pinta:
<%
usuario=request.form("usuario")
pass=request.form("pass")
sql="SELECT * FROM usuarios WHERE user='" & usuario & "' and pw='" & pass & "'"
.... y abrir un recordset sobre ese SQL
.... para comprobar si existe el usuario tecleado
%>
El problema es que pasamos al motor de SQL la cadena que tecleo el usuario, tal y como la tecleó el usuario.
SQL Injection es una tecnica de ataque que consiste en aprovecharse de esto.
De entrada parece algo "tonto" que tecleando cosas ahi puedan modificar
nuestra base de datos o conseguir acceso a zonas restringidas de nuestro web.
Pero supongamos en el caso anterior que por ejemplo la cadena tecleada fuera:
usuario:" a' or true "
pass : " a' or true "
La cadena resultado sería
SELECT * FROM usuarios WHERE user='a' or true and pass='a' or true
Y esto ya no suena tan bien.
Hay cosas peores; pueden llegar a inyectar un comando SQL
(DROP, UPDATE,
etc.) que modifique realmente nuestra base de datos, o incluso sacar nombres y passwords
reales de la misma.
No voy a entrar en profundidad en "lo que nos podrian hacer" sino en como
evitarlo:
Tenemos que tener cuidado en todos los parametros recogidos por formulario
(o querystring) que vayan a formar parte de una consulta SQL,
sobre todo en apartados criticos como la validacion de usuarios, pero en general en todas
partes.
Realmente lo que tenemos que evitar es que, al formar la cadena SQL, ésta tenga
un "sentido" distinto al esperado. Para ello, una vez leido el parámetro,
debemos tratarlo antes de meterlo en la SQL , quitandole cosas peligrosas.
Por ejemplo:
<%
usuario=request.form("usuario")
pass=request.form("pass")
usuario=limpia(usuario)
pass=limpia(pass)
sql="select * from usuarios where user='" & usuario & "' and pw='" & pass & "'"
....
funcion limpia(t)
dim tt
tt=t
tt=replace(tt,"""","")
tt=replace(tt,"'","")
tt=replace(tt,"--","")
' convendria tambien un
tt=server.htmlencode(tt)
limpia=tt
end funcion
%>
Se puede (y se debe) mejorar mucho esa funcion, pues dependiendo de nuestro
ASP en muchas ocasiones deberemos eliminar también palabras como
DELETE, UPDATE,
DROP, etc.. Para ampliar conocimientos sobre
este tema recomiendo la lectura del documento de Chris Anley