Detective no es programador: es quien trae la lista
La IA te devolvió el login y funciona. Pero "funciona" no es "es seguro": el código generado puede funcionar exactamente porque hace las cosas mal —guardar la contraseña en texto plano para poder compararla, quitar el permiso para que no salga error—. Tu ventaja como builder: no necesitas entender cada línea; necesitas escanear con lista de señales, como un inspector de vivienda que no construyó la casa pero sabe dónde huele a humedad.
[La rutina de escaneo: cuatro pasadas]
Esta actividad interactiva ('Explicacion visual') requiere el motor completo de Lumbre. El contenido estatico se muestra arriba; para la experiencia interactiva, visita la version online de este objeto.
Las siete señales
| # | Señal | Cómo se ve | Por qué duele |
|---|---|---|---|
| 1 | Secretos en el código | const API_KEY = "sk-abc123…" a la vista en un archivo | viaja al repo, a la copia, al navegador: filtración eterna |
| 2 | SQL cosido con más | WHERE email = ' + correo + ' | la puerta clásica del SQL injection (M10) |
| 3 | Validación solo del lado de afuera | el required está en el formulario y no en el servidor | cualquiera llega al servidor con una petición directa |
| 4 | Permisos en abierto | ruta de borrado/edición sin chequear quién es | el usuario 2 borra al usuario 1 "porque funciona" |
| 5 | Errores tragados | catch { } vacío: si algo falla, nadie se entera jamás | el fallo silencioso es el bug que nunca se arregla |
| 6 | CORS con estrella en algo con sesión | access-allow-origin para todo el mundo en rutas privadas | invita a otros sitios a montar tu API (M10-OA02) |
| 7 | Datos personales al log | el log imprime correo, teléfono o la petición completa | la bitácora se vuelve la filtración que no atacaron |
Escena del crimen: veinte líneas, cinco señales
const API_KEY = "sk-prod-9f2c8a1b…"; // senal 1: secreto en el codigo\n\napp.get("/busca", (req, res) => {\n const q = req.query.q;\n // senal 2: SQL cosido con +\n const sql = "SELECT * FROM clientes WHERE nombre LIKE '%" + q + "%'";\n db.run(sql, (err, rows) => {\n if (err) { } // senal 5: error tragado\n console.log("busqueda:", q, rows); // senal 7: datos al log\n res.json(rows);\n });\n});\n\n// senal 6: cors estrella en ruta con sesión\napp.use((req, res, next) => {\n res.setHeader("Access-Control-Allow-Origin", "*");\n next();\n});\n\n// senal 4: la ruta de arriba no chequeo quien es: cualquiera busca todos los clientesPara reforzar
Migraciones, respaldos y evitar el SQL injection
La señal 2 a fondo: por qué el parámetro separado cierra la puerta que el más abre.
Prueba
En el código del ejemplo, un atacante escribe como búsqueda: ' OR 1=1 -- . ¿Qué ocurre por la señal 2?
La señal 5 (catch vacío) solo es un problema estético: el error igual ocurrió.
Detecta el escaneo mal hecho
Cuatro alumnos revisan código generado antes de aceptarlo. Señala el escaneo que NO encuentra las siete señales:
- Busca con ctrl-f password, secret, key, token y api dentro del código.
- Lee el código con atención buscando "cosas que se vean raras".
- Verifica que cada ruta privada tenga chequeo de sesión y de rol.
- Revisa que los catch vacíos y los console.log con datos crudos no existan.
Identifica la linea con error.
Pasa el escaneo de cuatro pasadas al último archivo crítico que la IA te generó (login, subida de archivos o el que toque datos). Anota las señales encontradas —o "cero señales" con la evidencia de cada pasada— y pídele la corrección de cada una con la señal nombrada: «tienes SQL cosido con más (señal 2); paramétrizalo».