Cuando me toca explicar la fortificación de aplicaciones web hay que hablar obligatoriamente del impacto que tienen los bus de SQL Injection y de cómo poder limitarlos aplicando las reglas de Mínimo Punto de Exposición y Minima Superficie de Exposición. Una de las areas donde se puede tener un buen resultado, es en la utilización del propio sistema de seguridad del motor de bases de datos que se esté utilizando, aprovechando un esquema múltiple de conexiones a bases de datos y permisos restringidos a cada uno de ellas.
Bases de datos sin compartición de usuarios
Cuando se va a conectar una aplicación web a una base de datos, es necesario contar con al menos un usuario de la base de datos que tenga permisos en el SGBD. Con ese usuario, al menos, se hará la cadena de conexión para gestionar los datos que se almacenen en la base de datos que que allí se cree. Uno de los errores más comunes que se encuentran es que ese usuario al final se puede usar en varias bases de datos creadas dentro del mismo SGBD - algo muy común en entornos Microsoft SQL Server - o que tenga acceso a esquemas creados para otras aplicaciones - algo muy común en entornos Oracle Dabatabase -.
Figura 1: Mala gestión de conexiones a bases de datos en un SGBD |
Esto lleva a que al final, si alguien es capaz de localizar un bug de SQL Injection en una aplicación web conectada a una base de datos, con el mismo usuario que la aplicación usa para conectarse a esa base de datos es capaz de conectarse a otras bases de datos y sacar datos de ella.
Figura 2: Bases de datos con usuarios aislados |
Para evitar eso, cada base de datos de aplicación debe poder ser accedida única y exclusivamente por el/los usuarios que vayan a ser utilizados en la conexión de esa aplicación. Si alguien intenta acceder a esa base de datos desde otra cadena de conexión, deberá recibir un mensaje de error.
Figura 3: Error de conexión al intentar cambiar de base de datos con un bug de SQL Injection |
Dentro de una aplicación web, conexiones distintas para cada rol
Supongamos que tenemos una aplicación web expuesta en Internet en la que los usuarios que allí se creen tienen tres roles. Vamos a suponer que estos tres roles son: Rol Administrador que puede leer, escribir todas las tablas que dan soporte a la aplicación, el Rol Editor, que pueden escribir y borrar registros en tres tablas, y el Rol Lector que solo puede leer datos de dos tablas.
A estos roles, hay que sumar que la propia aplicación web, en algún momento puede tener que realizar algunas acciones no dependientes de las acciones de los usuarios, por ejemplo la autenticación de las credenciales, las operaciones de mantenimiento, etcétera. Para ello, hablaremos del Rol de Aplicación.
Lo suyo es que, para dejar un entorno fortificado se creen dentro de la base de datos cuatro usuarios que representen a los cuatro roles con los que se va a conectar la aplicación web. Cada uno de esos usuarios de la base de datos tendrá asignados los privilegios sobre el sistema necesarios para el cumplimiento de su rol dentro de la aplicación web, así como los permisos sobre los objetos estrictos y nada más.
Figura 4: Tabla de roles y permisos |
A partir de ese momento, la aplicación web no gestionará una única cadena de conexión, sino que gestionará 4 cadenas de conexión distintas para cada una de las acciones que quiera realizar. Por ejemplo, para hacer un proceso de login con un usuario, la aplicación web primero creará una conexión con el usuario del Aplicación, autenticará las credenciales que le introduzcan contra su tabla_usuarios, y una vez que se sepa el rol que deberá tener ese usuario dentro de la aplicación web, se cerrará la conexión con el Rol_Aplicación y se abrirá una nueva conexión con el usuario de la base de datos con el rol adecuado.
Figura 5: Esquema de cadenas de conexión múltiples desde la misma aplicación web a la misma base de datos |
Esto lo que hace es que, si un usuario con el Rol_Lector encuentra un bug de SQL Injection dentro de la aplicación, el impacto que puede tener estará limitado. Por el contrario, lo habitual es que las aplicaciones web solo gestionen un único usuario de conexión con todos los permisos sobre todos los objetos de la base de datos, lo que lleva a que cualquier usuario de la aplicación web que encuentra un bug de SQL Injection acabe teniendo acceso a todos los objetos de la base de datos, ya que el usuario que está utilizando la aplicación web en la conexión a la base de datos los tiene.
Saludos Malignos!
No hay comentarios:
Publicar un comentario