sábado, 4 de octubre de 2008

Seguridad en PHP: Inyecciones SQL

Como lo prometido es deuda, voy a segmentar el tema Seguridad PHP en varias partes, debido a que es un tema delicado y en que debo enfatizar en el porqué de cada medida de seguridad.

Entrega 1: Inyecciones SQL

¿que qué es una SQL Inyection?: es un método para alterar la cadena SQL y que el interprete de la base de datos ejecute otras acciones perjudiciales para el sistema; la más simple que voy a explicar aquí trata de vulnerar a la mayoría de los sistemas que INICIAN SESIÓN desde una tabla en su base de datos; debo aclarar que ésta técnica NO ES CORRECTA para empezar, pero como la mayoría lo ha echo así, no me queda más remedio que indicarles las providencias necesarias para resolver éste problema.

Supongamos que su sentencia para iniciar sesión sea esta:
$usuario=$_POST['usuario'];
$contra=$_POST['contra'];
$sql = "SELECT * FROM usuarios WHERE user='".$usuario."' AND password='".$contra."';";
if (mysql_fetch_array(mysql_query($sql,$coneccion))) {
//acceso al sistema
}

Como podemos ver ésta sentencia devuelve TRUE en el caso de que se encuentre el usuario y la contraseña correctos dándole acceso al sistema, pero en el caso de que sea un cracker el que envía un formulario falso en donde coloque en la variable del POST $usuario el siguiente valor: ' OR 1=1 #
Pues sencillamente el carácter de apóstrofo (') cerraría la cadena en SQL y con el OR 1=1 quedaría que user='' OR 1=1 que devuelve TRUE y para rematar el carácter numeral (#) que en la mayoría de las bases de datos es el de comenzar comentarios, lo que significaría que se ignoraría el resto de la consulta quedando así para el interprete SQL: SELECT * FROM usuarios WHERE user='' OR 1=1 y por ende el resultado sería TRUE, otorgándole acceso al sistema.

¿Cómo puede ser?, ¿hay manera de evitarlo?, Las Magic Quotes activadas en PHP en la MAYORÍA DE LOS CASOS lo resuelven, pero ésta no es la única forma de SQL Inyection que existe y las Magic Quotes no lo resuelven todo, consulten el manual de PHP (Tópico: Seguridad en bases de datos/Inyección SQL) y verán lo que es bueno...; en fin, les daré los consejos fundamentales para evitar un SQL Inyection:
  • Revisa que no existan cadenas ni caracteres como éstos: (OR, AND, ', -- y #) en las variables del POST.
  • Escapa las cadenas con mysql_real_escape_string o addslashes ¡es mejor que las magic quotes!
  • Si la variable es numérica, verifica que lo sea con is_numeric().
  • NUNCA utilices al usuario administrador de la base de datos, crea uno con el acceso y privilegios necesarios.
  • HASHEA las contraseñas ¡por favor!, si no sabes de que te hablo busca en google Hash o MD5 y con eso te digo todo.
  • No vuelvas a iniciar sesión así en tus futuros sistemas, de ser posible utiliza el sistema de privilegios de usuario y crearle un usuario de base de datos a cada usuario; ésta es la forma correcta de hacer las cosas, tarda mucho lo sé pero te da un sinfín de ventajas.
Y con esto doy por terminada la primera entrega de Seguridad en PHP ¡No apto para novatos!, espero que tu cerebro quede lo suficientemente aturdido como para seguir mis consejos, ¡hasta la proxima!.

No hay comentarios: