Humberto Miatello - aka Ruperto Chuquizutta

viernes, abril 14, 2006

Login - Un Error Frecuente

NOTA: usaré el lenguaje JAVA para ilustrar el código, pero el artículo afecta a muchos lenguajes de programación!!!

Como todos sabemos, la seguridad de nuestros sitios es esencial. Aquí presento un error común que muchos desarrolladores, sobre todo, newbies y aficionados comenten...


El login, a grandes rasgos, está compuesto por dos partes, el ingreso de usuario y contraseña y, la validación de éstos datos contra la base de datos.
El error radica en que muchos desarrolladores toman estos valores del objeto request y, los insertan directamente en un Query SQL para validarlos:

String user=request.getParameter("user");
String pass=request.getParameter("pwd");
String sql=
"SELECT * FROM USERS_TABLE WHERE USER='"+user+"' AND PASS='"+pass+"'"
database.consultar(sql);

Este código, para usuarios bien intencionados va a funcionar en algunos casos, a saber:
No se pueden incluir caracteres como comillas simples(') o comillas dobles("), entre otros caracteres, pues esto generará un error de sintaxis.
Lo peor de todo es si al usuario se le ocurriese poner comodines, o código SQL en los campos usuario y contraseña:

Ejemplo 1:

Datos:
user= humberto
pass= humberto' OR '1'='1

Codigo:
String user=request.getParameter("user");
String pass=request.getParameter("pwd");
String sql="SELECT * FROM USERS_TABLE WHERE USER='"+user+"' AND PASS='"+pass+"'"

database.consultar(sql);

Consecuencias
Estaríamos consultando a la base de tatos por:
SELECT * FROM USERS_TABLE WHERE USER='humberto' AND PASS='humberto' OR '1'='1'
Un hueco de seguridad terriblemente grande!!!, cualquiera accedería a nuestra aplicación!

Otro Ejemplo más ilustrativo, aunque distinto es:

Datos:
user= humberto
pass= humberto' OR '1'='1'; DELETE FROM USERS_TABLE'

Codigo:
String user=request.getParameter("user");
String pass=request.getParameter("pwd");
String sql="SELECT * FROM USERS_TABLE WHERE USER='"+user+"' AND PASS='"+pass+"'"

database.consultar(sql);

Consecuencias
Estaríamos consultando a la base de tatos por:
SELECT * FROM USERS_TABLE WHERE USER='humberto' AND PASS='humberto' OR '1'='1'
y, borrando toda la tabla de usuarios a través de:
DELETE FROM USERS_TABLE''
Nuevamente un hueco de seguridad, pero aquí, además de acceder a la aplicación, borran todos los usuarios registrados en nuestro sitio.

SOLUCION
Para estos casos, debemos tomarnos el trabajo (al menos una vez) de crear una clase o módulo que verifique los elementos como usuario y contraseña.
En ella, poner funciones comunes como trim (quita espacios en blanco) y, splits según caracteres especiales, comodines, comillas, etc.
Otra solucion es crear la consulta a la base de datos con sentencias preparadas, de esta forma, todos los caracteres que puedan afectar a nuestro codigo SQL se transformarán en secuencias de escape.

En el artículo, se muestra sólo el ejemplo de login. Pero estas técnicas se pueden utilizar en cualquier lugar (ABM - Altas bajas y modificaciones), que luego, sean tomados dichos datos para manipular la base de datos.
Debemos ser conscientes y cuidar nuestras aplicaciones acerca este tipo de errores, como también, advertir a webmasters que sus sitios tienen estas fallas.