Habilidad de Auditoría de Seguridad
Realiza una auditoría de seguridad estática rigurosa del código fuente de una aplicación web. Produce una tabla resumen (PASS / FAIL / MANUAL-REVIEW) y bloques por hallazgo con evidencia archivo:línea, descripción del riesgo y código de corrección.
Fase 1 — Triaje de la Pila
Antes de escanear cualquier código, responde estas preguntas leyendo package.json, archivos de configuración y README:
- Framework: SvelteKit / Next.js / Express / FastAPI / etc.
- Controlador de base de datos: parametrizado (libsql, pg, prisma) vs. cadena cruda (drivers de bajo nivel)
- Mecanismo de autenticación: JWT / tokens HMAC / sesiones / OAuth
- Destino de despliegue: Fly.io / Cloudflare / Vercel / Node sin framework — determina qué cabecera IP confiar para limitación de tasa y registros de auditoría (
Fly-Client-IPvsCF-Connecting-IPvsX-Forwarded-For); confiar en la incorrecta permite a un atacante falsificar su IP de origen - Subidas de archivos: sí/no — si sí, dónde se almacenan (FS local, compatible con S3, CDN)
- Llamadas salientes externas: API de correo, webhooks, obtención de medios — superficie potencial de SSRF
Expón tu resumen de la pila en un párrafo antes de la Fase 2. Suposiciones incorrectas aquí producen hallazgos incorrectos.
Fase 2 — Escaneo
LECTURA OBLIGATORIA: references/security-checklist.md
NO cargues references/security-checklist.md para revisiones específicas de un solo endpoint — ampliará el alcance más allá de la tarea. Cárgalo solo para auditorías completas del código base.
Trabaja a través de cada categoría en la lista de verificación en orden — saltarse un grupo requiere una razón escrita en el informe.
Para cada categoría:
- Lee los archivos fuente relevantes. No marques PASS de memoria.
- Si el archivo no existe, marca MANUAL-REVIEW con una nota.
- Registra el veredicto (PASS / FAIL / MANUAL-REVIEW) y una nota de evidencia de una línea.
Si el repositorio es demasiado grande para leer cada archivo, prioriza por riesgo: flujos de autenticación y manejo de tokens primero, luego límites de entrada/salida, luego configuración de dependencias. Anota qué archivos se omitieron.
Fase 3 — Clasificación
Revisa tus notas de escaneo en bruto. Para cada elemento, aplica las reglas de veredicto:
- PASS — has leído el código relevante y confirmaste que el control está implementado. Cita archivo:línea.
- FAIL — encontraste una brecha confirmada y explotable. Tienes un fragmento. Puedes escribir una corrección.
- MANUAL-REVIEW — el veredicto requiere contexto de ejecución, acceso a infraestructura o juicio humano (p. ej. "verificar que este token tenga alcance de solo lectura en el panel de Turso").
Antes de asignar un veredicto, pregúntate: "¿Puedo escribir el código de corrección ahora mismo, usando solo lo que he leído?" Sí → FAIL. No → MANUAL-REVIEW.
No degrades un FAIL a MANUAL-REVIEW para suavizar el informe.
Fase 4 — Informe
Primero, la tabla resumen:
| # | Categoría | Estado | Notas |
|---|---|---|---|
| 1 | Inyección SQL | PASS | Parametrizado en todas partes |
| 2 | XSS | FAIL | {@html} en campo controlado por el usuario — ver hallazgo |
| … | … | … | … |
Luego, para cada FAIL y MANUAL-REVIEW, un bloque de hallazgo:
### [N]. CATEGORÍA — FAIL
**Archivo:** `src/lib/example.ts:42`
**Fragmento:**
cookies.set(name, token, { httpOnly: true }) // ← falta la bandera Secure
**Riesgo:** Cookie transmitida por HTTP plano en no producción; capturada por MITM pasivo.
**Corrección:**
cookies.set(name, token, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
});
Los bloques MANUAL-REVIEW usan el mismo formato pero reemplazan Corrección con Acción describiendo qué debe verificar el humano y dónde.
Los elementos PASS aparecen solo en la tabla resumen — sin bloques.
NUNCA
-
NUNCA marques PASS sin leer el archivo En su lugar: Lee el archivo, cita archivo:línea en la nota de evidencia. Por qué: Los veredictos PASS basados en memoria producen falsa seguridad — el punto de la auditoría es la evidencia.
-
NUNCA marques FAIL sin un fragmento de código En su lugar: Cita la(s) línea(s) vulnerable(s) exacta(s). Si no puedes encontrar un fragmento, es MANUAL-REVIEW. Por qué: Un FAIL sin evidencia es ruido; los desarrolladores necesitan la ubicación exacta para corregirlo.
-
NUNCA confundas FAIL y MANUAL-REVIEW En su lugar: FAIL = puedes escribir la corrección ahora mismo. MANUAL-REVIEW = no puedes, y dices por qué. Por qué: Mezclarlos destruye la capacidad de acción del informe.
-
NUNCA te saltes la Fase 1 de triaje de la pila En su lugar: Lee
package.jsony un archivo de configuración antes de escanear cualquier cosa. Por qué: En qué cabecera IP confiar, qué enfoque de CSP es válido y qué modelo de autenticación aplica depende de la pila — las suposiciones incorrectas se traducen en veredictos incorrectos. -
NUNCA informes código de corrección que no coincida con el framework/biblioteca del proyecto En su lugar: Escribe correcciones usando las APIs exactas ya en uso (p. ej. SvelteKit
cookies.set, nores.setHeader). Por qué: Las correcciones genéricas que no compilan se ignoran; las correcciones específicas del framework se fusionan. -
NUNCA escribas un bloque de hallazgo para una categoría cuyo archivo fuente no hayas leído En su lugar: Abre el archivo, léelo, luego escribe el bloque. Por qué: Un bloque de hallazgo sin evidencia de archivo es una afirmación, no una auditoría — erosiona la confianza en todo el informe cuando resulta ser incorrecto.
-
NUNCA omitas archivos en silencio en un repositorio grande En su lugar: Prioriza por riesgo (manejo de autenticación/tokens → límites de entrada/salida → configuración de dependencias) y enumera explícitamente cada archivo omitido en el informe. Por qué: Las omisiones silenciosas hacen que las afirmaciones de cobertura de la auditoría no sean verificables — un informe limpio en un escaneo incompleto se lee como un falso todo claro.