[SQL 16] Seguridad, permisos e inyección SQL
- Aplicar el principio de mínimo privilegio con
GRANT,REVOKEy roles. - Usar vistas para exponer solo las columnas permitidas.
- Explicar las propiedades ACID y usar transacciones para operaciones atómicas.
- Reconocer cómo funciona una inyección SQL y cómo se previene con consultas parametrizadas.
El DCL (Data Control Language) gestiona quién puede hacer qué: GRANT concede y
REVOKE retira privilegios (SELECT, INSERT, UPDATE, DELETE, EXECUTE…) sobre tablas, vistas o
procedimientos. Lo correcto es agrupar permisos en roles (analista, cajero, administrador) y dar a cada usuario
solo lo que necesita: mínimo privilegio.
Una vista es una herramienta de seguridad muy usada: se da permiso sobre la vista (que no incluye el salario) y no sobre la tabla completa.
El TCL controla transacciones con propiedades ACID: Atomicidad (todo o nada), Consistencia (se respetan las reglas), aIslamiento (las transacciones no se pisan) y Durabilidad (lo confirmado no se pierde).
La amenaza más famosa es la inyección SQL: si una aplicación arma el SQL pegando texto escrito por el usuario, este puede cambiar el sentido de la consulta. La defensa es usar consultas parametrizadas.
GRANT SELECT, INSERT ON esquema.tabla TO usuario; REVOKE INSERT ON esquema.tabla FROM usuario; CREATE ROLE analista; GRANT SELECT ON vista TO analista; GRANT analista TO ana; BEGIN; … COMMIT; -- o ROLLBACK
"… WHERE last_name = '" + entrada + "'"). Si la entrada es x' OR '1'='1, la condición pasa a ser siempre verdadera y la consulta devuelve todo.WHERE last_name = ?), validar las entradas, mínimo privilegio con GRANT/REVOKE, vistas para limitar columnas y un ORM que parametrice por ti. En QueryLab, además, cada sesión corre en una copia aislada en el navegador: no hay servidor que atacar.1 · Ejemplos guiados · ejecuta y modifica cada bloque
WHERE last_name = '[entrada]'. Con la entrada x' OR '1'='1 el filtro se anula y aparecen todos los empleados.x' UNION SELECT email, salary FROM employees -- el atacante obtiene datos de otras columnas. Por eso nunca se concatena la entrada.Sintaxis en otros motores (referencia, no se ejecuta aquí)
CREATE USER 'ana'@'%' IDENTIFIED BY 'Clave$egura2025'; CREATE ROLE 'analista'; GRANT SELECT ON hr.directorio TO 'analista'; -- solo la vista GRANT 'analista' TO 'ana'@'%'; SET DEFAULT ROLE 'analista' TO 'ana'@'%'; REVOKE SELECT ON hr.directorio FROM 'analista'; SHOW GRANTS FOR 'ana'@'%';
CREATE ROLE analista; GRANT SELECT ON hr.directorio TO analista; GRANT analista TO ana; GRANT EXECUTE ON reajustar_depto TO rrhh; REVOKE SELECT ON hr.directorio FROM analista;
?).# VULNERABLE: el texto del usuario se mezcla con el SQL
cur.execute("SELECT * FROM usuarios WHERE login = '" + login + "'")
# SEGURO: el valor viaja como parámetro y nunca se ejecuta como código
cur.execute("SELECT * FROM usuarios WHERE login = ?", (login,))
⚠ Errores frecuentes
- Conceder
ALL PRIVILEGESa la cuenta de la aplicación: si la comprometen, el atacante puede borrar todo. - Creer que «escapar comillas a mano» basta: los parámetros son la defensa correcta.
- Mostrar los mensajes de error de la base al usuario final: revelan nombres de tablas y columnas.
- Dejar operaciones de varios pasos fuera de una transacción: si falla a la mitad, los datos quedan inconsistentes.
2 · Retos con corrección automática
Escribe tu solución y pulsa comprobar (Ctrl + Enter). Tu consulta y la solución se ejecutan en bases limpias y se comparan los resultados: no importan los nombres de las columnas, sí los datos (y el orden, cuando el reto lo pide). Si te atascas, usa la pista o mira el resultado esperado.
3 · Preguntas tipo solemne
employees?