Hace un ao (2000) descubrimos un grave problema de seguridad que potencialmente poda afectar a muchos sitios web segurizados, con validacin a travs de usuario y clave. Nos tomamos un tiempo para definir el problema y chequear a cuntos sitios web afecta. Los resultados son sorprendentes.

Qu sitios pueden tener este problema de seguridad?

El problema afecta a sitios web que utilizan Bases de Datos para contener el listado de pares usuario/clave, pginas ASP para accederlas, y cuyas rutinas de validacin de usuario utilizan consultas SQL escritas de una determinada manera.

El algoritmo de validacin de usuarios

Muchos desarrolladores web validan el acceso de usuarios a travs del siguiente mtodo, implementado adems por el sistema de autentificacin de usuarios (Server Behavior) de Macromedia Dreamweaver Ultradev 4 (ltima versin a la fecha):

Se pide al usuario que ingrese el par usuario/clave en campos TEXT y PASSWORD, respectivamente, de un formulario en una pgina HTML convencional. 
Al hacer click sobre el botn SUBMIT del formulario, estos datos son pasados ocultamente a una pgina ASP en el encabezado HTTP, ya que la etiqueta FORM generalmente tiene (y debera tenerlo siempre en estos casos) el atributo METHOD="POST". 
La pgina ASP toma los datos de usuario y clave. 
Se realiza una consulta SQL contra la base de datos para traer el registro que corresponde al usuario y clave ingresados. 
Si la consulta devuelve un registro, entonces los datos son correctos, el usuario es reconocido por el sistema, y se crea una variable de sesin que lo habilita de aqu en adelante a ingresar a las partes segurizadas del sitio a las cuales tiene acceso. Si la cantidad de registros devueltos es nula es porque no se ha encontrado ningn par usuario/clave coincidente en la tabla de usuarios. Si es as, se enva a la persona a otra pgina donde se le indica que hay un error en los datos ingresados. 

El cdigo de validacin en ASP

La pgina ASP que recibe los datos de usuario y clave, los recupera con las siguientes instrucciones:

str_usuario = Request.Form("usuario")
str_clave = Request.Form("clave")

y utiliza una consulta SQL contra la base de datos para devolver el registro correspondiente al usuario. La cadena SQL es como sigue (en una sola lnea):

cad_sql = "SELECT * FROM tabla_usuarios WHERE col_usuario = '" & str_usuario & "' AND col_clave = '" & str_clave & "'"

Como vemos, se van concatenando las instrucciones SQL con la informacin proveniente del formulario donde el visitante al sitio web ingres sus datos.

Luego se ejecuta la consulta y se verifica si devuelve un registro o no. En funcin de ello se habilita o no al usuario.


Dnde aparece el problema?

Qu pasa si en el campo USUARIO del formulario web de validacin se introduce el siguiente texto:

' OR col_usuario LIKE '%%

y en el campo CLAVE lo siguiente (aunque se vea como asteriscos),

' OR col_clave LIKE '%%

Cuando se concatenan los datos en la consulta SQL, la cadena definitiva quedar como sigue (en una sla lnea; se muestra as para mayor claridad):

SELECT * FROM tabla_usuarios
WHERE col_usuario = ''
OR col_usuario LIKE '%%'
AND col_clave = ''
OR col_clave LIKE '%%'


LA CUAL, SI LA ANALIZAMOS LOGICAMENTE, SIEMPRE DEVOLVERA TODOS LOS REGISTROS DE LA TABLA DE USUARIOS. POR LO TANTO, EL NUMERO DE REGISTROS DEVUELTOS SERA DISTINTO DE CERO Y EL SISTEMA NOS ACEPTARA COMO USUARIOS.

As, se consigue ser validado por el sistema sin siquiera saber como cul usuario se ha ingresado.

Notar que este problema no es tal en otros lenguajes que no permiten la expansin de variables. En PHP, por ejemplo, una comilla simple pasada a travs de un mtodo GET o POST es tomada como '\. Es decir, la comilla seguida de una barra invertida. Esto no se puede cambiar, salvo que el administrador del servidor modifique la configuracin por defecto de esta propiedad en uno de los archivos ini del intrprete PHP.

Ahora, muchos se estarn preguntando cmo s los nombres de los campos (columnas) de la tabla. Generalmente, los programadores/desarrolladores colocan en el formulario de ingreso de usuario/clave los mismos nombres de las columnas de la tabla en las etiquetas INPUT.

Usuario: <input type="text" name="usuario">
Clave: <input type="password" name="clave">

As, con slo observar el cdigo de la pgina HTML de ingreso de datos, posiblemente se obtenga la informacin necesaria.

Sino, se puede inducir un error en la consulta SQL, por ejemplo de la siguiente manera,

usuario --> ' OR col_usuario LIKE '%%'
clave --> cualquier texto

Simplemente se ha agregado una comilla al final del nombre de usuario comentado anteriormente. Cuando se concatenen las cadenas de texto, quedar una comilla sin cerrar, lo cual, cuando se ejecute la consulta contra la base de datos, producir un error en la API de acceso a datos (OLE DB) que saldr en la pantalla, probablemente junto a la cadena completa de la consulta. De all simplemente se leen los nombres de los campos que el desarrollador ha asignado.

Pero la cosa es ms sencilla an. No se necesitan conocer los nombres de los campos usuario y clave de la tabla. CON SOLO CONOCER EL NOMBRE DE UN CAMPO CUALQUIERA DE LA TABLA, IGUAL SE PODRA ACCEDER COMO USUARIO VALIDADO.

Veamos, supongamos que la tabla de usuarios contiene otro campo, adems de usuario y clave, llamado NOMBRE. Entonces, si en el formulario HTML de validacin se ingresa lo siguiente en los campos usuario y clave

usuario --> ' OR NOMBRE LIKE '%%
clave --> ' OR NOMBRE LIKE '%%

la cadena de consulta concatenada quedar

SELECT * FROM tabla_usuarios
WHERE col_usuario = ''
OR NOMBRE LIKE '%%'
AND col_clave = ''
OR NOMBRE LIKE '%%'

La cual, si la analizamos, nos devolver nuevamente todos los registros de la tabla y la validacin es positiva.


Ingresando como un usuario especfico

Con los cdigos utilizados anteriormente no se sabe de antemano como cul usuario se va a ingresar. sto depender del primer registro obtenido en el Recordset que trae la consulta.

Para ser ms especfico, se puede modificar la cadena SQL. Por ejemplo, para ingresar como una persona cuyo usuario contenga la cadena ana, se debe colocar:

usuario --> ' OR NOMBRE LIKE '%ana%
clave --> ' OR NOMBRE LIKE '%ana%

NO OLVIDEMOS QUE ESTOS DATOS SE INGRESAN EN LOS CAMPOS USUARIO Y CLAVE DE LA PAGINA DE LOGIN, A LA QUE TODO EL MUNDO TIENE ACCESO.

Es ms, si se conoce el nombre de un usuario determinado, se puede ingresar al sistema validados como tal. Por ejemplo, supongamos un usuario llamado JOSE; para ingresar como l, se debe introducir lo siguiente

usuario --> JOSE
clave --> ' OR col_usuario = 'JOSE

La cadena concatenada quedar de la siguiente manera:

SELECT * FROM tabla_usuarios
WHERE col_usuario = 'JOSE'
AND col_clave = ''
OR col_usuario = 'JOSE'

Esta consulta devolver slo el registro correspondiente al usuario JOSE. Por lo tanto, el sistema nos validar como el mismo.

Qu pasa si el campo de ingreso de datos est limitado a un nmero reducido de caracteres?

La solucin a este planteo debe resultar trivial para cualquier desarrollador web con mnima experiencia. Aunque algunos webmasters creen que estn aadiendo una cuota de seguridad cuando limitan la longitud de caracteres en los campos TEXT y PASSWORD, esto no es as. Simplemente se guarda la pgina que contiene el formulario en el disco duro local, se abre con un editor web (o de textos) y se quitan los atributos MAXLENGTH="XX" de las etiquetas INPUT. Se guarda la pgina en el disco local, previa correccin del atributo ACTION del formulario para que apunte a la pgina ASP del sitio de acceso segurizado. Se ejecuta la pgina localmente en el explorador/navegador, se cargan los valores antedichos de usuario y clave, y listo.


Uno de cada tres sitios ASP de acceso seguro son vulnerables

En las pruebas realizadas en estos meses, tratamos de ingresar a un centenar de sitios segurizados a travs de bases de datos mediante el mtodo comentado. Cerca del 40% por ciento de estos sitios pudo ser vulnerado sin ningn esfuerzo.

Por otro lado, como se coment al principio, Macromedia Dreamweaver Ultradev 4 implementa el algoritmo que hace posible esta vulnerabilidad en la seguridad. Por lo tanto, todos los desarrolladores que utilizaron este popular programa para implementar la seguridad de sus sitios, mediante el "Server Behavior" de autentificacin de usuarios, muy probablemente tengan este hueco de seguridad en sus sitios web.

Algunos de los sitios que muestran esta falencia de seguridad poseen la certificacin de seguridad estampada en sus pginas. No se si las empresas certificadoras de seguridad tienen algo de culpa. Estrictamente, se est trabajando en un entorno Secure Socket Layer (SSL). Cuando comienza la transaccin segura, los cdigos SQL ingresados en lugar de usuario/clave son encriptados y viajan "seguros" para que nadie pueda verlos con un sniffer y una llave de protocolos. Luego son desencriptados en el servidor seguro e impactan contra la base de datos, produciendo una transaccin "seguramente" insegura.


Cmo solucionar el problema?

Este artculo no tiene como objetivo ensear a entrar a sistemas segurizados. Slo estamos diciendo: - Hay un frecuente problema de seguridad y quizs su sitio lo posea. Si usted es desarrollador, trate de vulnerar con este mtodo las zonas de sus sitios restringidas a usuarios registrados. Si su sitio es susceptible, a continuacin le explicamos como solucionar el problema.

Corregir este defecto es sencillo. Slo hay que modificar la manera en que se recuperan los datos de usuario y clave en la pgina ASP. Por ejemplo, de la siguiente manera:

str_usuario = Replace(Request.Form("usuario"),"'","''")
str_clave = Replace(Request.Form("clave","'","''")

Observar que se ha aadido la funcin Replace() de VBScript. Esta funcin reemplazar cada comilla simple que pueda llegar a ingresar el usuario por dos comillas simples seguidas. Esto es tomado como el caracter comilla simple por la interfase de datos de Microsoft y no afectar la estructura de la consulta SQL. As, se evitar que un usuario pueda interceptar la consulta SQL y agregar cdigo propio.

Argentina-Hosting.Com
http://www.argentina-hosting.com