Saltar al contenido
Bases de datos con SQL
Todos los cursos

Ejercicio: Seguridad: inyección SQL, contraseñas y copias

  • ⏱ 35 minutos
  • 📶 Nivel: principiante

Objetivo

Detectar una consulta vulnerable, escribir su versión parametrizada y aplicar contraseñas con hash, permisos mínimos y copias de seguridad.

Cómo se trabaja

Puedes razonar en papel o ejecutar las consultas con sqlite3 sobre la tabla usuarios de la lección. El objetivo es que reconozcas el problema y sepas escribir la forma segura.

Pasos

Marca cada paso a medida que lo completes. Tu avance se guarda en este navegador.

💡 Pista 1: el paso 1

Sustituye en la plantilla el nombre por el texto indicado y observa dónde empieza el comentario --.

💡 Pista 2: el paso 4

Crea el rol con CREATE ROLE … LOGIN PASSWORD y concede SELECT sobre las tres tablas (puedes listarlas separadas por comas).

✅ Ver una solución posible

Intenta resolverlo antes de mirar. Tu versión puede ser distinta y también correcta.

Paso 1: la consulta resultante
SELECT id, nombre, rol FROM usuarios WHERE nombre = 'x' OR '1'='1' --' AND clave = 'nada'
idnombrerol
1anacliente
2adminadministrador

Todo lo que viene después de -- es un comentario, así que la comprobación de la clave desaparece y la condición '1'='1' es siempre verdadera: devuelve 2 filas (todas).

Paso 2
const fila = db
  .prepare('SELECT id, nombre, rol FROM usuarios WHERE nombre = ? AND clave_hash = ?')
  .get(nombre, hash);

(Aún mejor: busca solo por nombre y compara el hash con bcrypt.compare, como en la sección 3.)

Paso 3
CREATE TABLE usuarios (
  id         INTEGER PRIMARY KEY,
  nombre     TEXT NOT NULL UNIQUE,
  clave_hash TEXT NOT NULL,
  rol        TEXT NOT NULL DEFAULT 'cliente'
);

-- Node.js
const hash = await bcrypt.hash(clave, 12);        // al registrar
const ok = await bcrypt.compare(clave, clave_hash); // al acceder
Paso 4
CREATE ROLE reportes LOGIN PASSWORD 'una-clave-larga-y-unica';
GRANT SELECT ON clientes, pedidos, lineas_pedido TO reportes;
Paso 5
# SQLite
sqlite3 tienda.db ".backup 'copia.db'"
cp copia.db tienda.db        # restaurar

# PostgreSQL
pg_dump -U postgres -F c -f tienda.backup tienda
createdb -U postgres tienda_restaurada
pg_restore -U postgres -d tienda_restaurada tienda.backup

💡 🏁 Reto extra (opcional)

Haz una lista de comprobación de seguridad de 8 puntos para una aplicación web con base de datos y revisa con ella el proyecto final del curso.