Lo prometido es deuda, por favor lean este post con musica de fondo de Richard Claiderman.
buenos dias don Juan
la primera seria limitar el numero de caracteres a utilizar como login y/o password.
evitar usar (espacio) - = * ' ; tanto en login como password, si detectas cualquiera de estos caracteres cancela el script antes de ejecutar la query.
en otras palabras, no permitas que usen login como: El gran usuario
y no permitas que usen password como: El gran password
(por los espacios)
rastrear palabras como select, drop, delete, etc. tanto en el login y el passwords ya que son comandos usados principalmente por mysql y/o mssql.
esto no solo para login y password sino para cualquier valor retornado, recuerda que lo que se obtiene del cliente no presisamente es lo que se deberia recibir, asi que desconfia de todo lo que te manden.
y muy importante!
en un query para validar un login y password es muy comun verificar si hay algun resultado, asi que olvidate de verificar: si recibiste mas de 0 (cero) registros entonces el login y password es correcto, esa es la mejor puerta abierta al inyection.
busca primero el login, si regreso valores entonces compara el password contra el registro que se recibio, si coincide entonces es un login valido.
aqui un mal ejemplo
select * from usuarios where login=? and password =?
si regresaron registros entonces es correcto., se da por hecho que el usuario existe (Error)
buen ejemplo
select * from usuarios where login=?
si regreso 1 solo registro entonces
si $password=password entonces es correcto
recuerda, nunca des nada por hecho ya que al final el response que recibes de tu pagina QUIEN SABE si sera de un usuario o cliente.
ahora bien, como funciona el inyection?
recuerda que en sql se pueden enviar varios querys al mismo tiempo, eso es lo que facilita el inyection
imagina este query
Select * from usuarios where login='$login' and password='$Password'
este seria el query para buscar un usuario X, que pasa si escribes un login correcto? este se ejecutaria asi:
Select * from usuarios where login='El Gran Login' and password='El Gran Password'
si retorna cualquier registro se da por hecho que el usuario existe (dar por hecho es el primer gran error del programador)
ahora bien, que pasa si en vez de 'El Gran Login' se escribe:
' and 1=1 --
lease Comilla and 1=1 guion guion
el query quedaria de este modo
select * from usuarios where login = '' and 1=1 -- and password = 'y lo que sea se este en password, o nada si es que se dejo en blanco'
bueno, sql va a ignorar lo que sea que este despues de --
asi que el query va a regresar los 100mil usuarios que hay en la base de datos, capichi????
luego verificas que se haya regresado mas de cero registros, lo cual es cierto y ... listo, un login invalido dado por bueno.
y eso que SOLO uso parte de un query como login.
imagina lo que va a pasar si manda borrar la base de datos de usuarios con un delete, o les cambia el password a todos con un update, o simplemente te manda borrar toda la base de datos junto con todas las tablas usando un drop.
plop?!?!?! (o sea, entendiste???)
la mejor arma contra el inyection es entender como funciona.