queryLab · software_de_entrenamiento en espera
Nivel 4 · Avanzado · SQL · DCL · TCL · seguridad

[SQL 16] Seguridad, permisos e inyección SQL

GRANT/REVOKE, vistas como capa de seguridad, ACID e inyección SQL y su defensa.
0 / 4 retos resueltos 📘 Mapa de SQL · DCL (GRANT, REVOKE) y TCL (COMMIT, ROLLBACK)
Al terminar esta práctica podrás…
  • Aplicar el principio de mínimo privilegio con GRANT, REVOKE y 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.

Sintaxis
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
GRANT / REVOKE
Conceden y retiran privilegios sobre objetos.
Roles
Paquetes de permisos que se asignan a usuarios.
Mínimo privilegio
Cada cuenta solo con lo indispensable.
Vista de seguridad
Expone columnas permitidas y oculta las sensibles.
ACID
Atomicidad, Consistencia, aIslamiento y Durabilidad.
Consulta parametrizada
El dato viaja aparte del SQL y nunca se ejecuta como código.
⚠ el errorEl error: concatenar la entrada del usuario dentro del texto SQL ("… 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.
✓ la defensaLa solución: consultas parametrizadas / prepared statements (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

01Vista como capa de seguridad
Un directorio que muestra datos de contacto pero oculta salario y comisión. En producción se da GRANT sobre la vista y no sobre la tabla.
sql-seguridad.sql
Presiona «ejecutar» para ver el resultado.
02Cómo se ve una inyección
La aplicación arma WHERE last_name = '[entrada]'. Con la entrada x' OR '1'='1 el filtro se anula y aparecen todos los empleados.
sql-seguridad.sql
Presiona «ejecutar» para ver el resultado.
03Inyección con UNION: robo de datos
Más grave: con x' UNION SELECT email, salary FROM employees -- el atacante obtiene datos de otras columnas. Por eso nunca se concatena la entrada.
sql-seguridad.sql
Presiona «ejecutar» para ver el resultado.
04La entrada tratada como dato
Si el valor se trata como dato (lo que hace un parámetro), la misma cadena simplemente no coincide con ningún apellido.
sql-seguridad.sql
Presiona «ejecutar» para ver el resultado.
05Atomicidad: transferir presupuesto
Mover 1000 de un salario a otro debe ocurrir completo o no ocurrir: se agrupa en una transacción.
sql-seguridad.sql
Presiona «ejecutar» para ver el resultado.

Sintaxis en otros motores (referencia, no se ejecuta aquí)

MySQL Usuarios, roles y permisos
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'@'%';
Oracle Permisos en Oracle
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;
Python Consulta vulnerable vs. parametrizada
El mismo login escrito mal (concatenando) y bien (con parámetro ?).
# 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 PRIVILEGES a 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

1. ¿Qué sentencia retira a un usuario el permiso de borrar en employees?
2. ¿Cuál es la defensa principal contra la inyección SQL?
3. La «A» de ACID significa…
4. ¿A qué sublenguaje pertenecen COMMIT y ROLLBACK?