El Checklist de Seguridad del Fundador: Cómo Lanzar un MVP Vibe-Coded Sin Que Te Hackeen (Parte 8)

Serie Vibe Coding Security

  1. ¿Qué es la Seguridad del Vibe Coding? Una Guía de Campo para 2026
  2. El OWASP Top 10 para Aplicaciones Vibe-Coded
  3. Anatomía de una Brecha de Vibe Coding: Lecciones de los Peores Incidentes de 2026
  4. La Trampa de las Dependencias: Riesgos en la Cadena de Suministro del Código Generado por IA
  5. Autenticación y Secretos: Lo Que la IA Siempre Hace Mal
  6. Escaneando Aplicaciones Vibe-Coded: Por Qué el SAST/DAST Tradicional Se Queda Corto
  7. Prompt Engineering para Código Seguro
  8. El Checklist de Seguridad del Fundador (estás aquí)
  9. Asegurando el Pipeline de Codificación IA
  10. El Futuro de la Seguridad del Vibe Coding

Tiempo de lectura: 18 minutos

TL;DR

Has construido tu MVP con IA. Funciona, los usuarios se están registrando y estás pensando en el lanzamiento. Antes de hacerlo, recorre estas quince comprobaciones. Cubren las vulnerabilidades que veo con más frecuencia en aplicaciones vibe-coded — las que llevan a brechas de datos, credenciales filtradas y correos de «tenemos que cerrar todo» enviados a tus usuarios. Cada comprobación tiene un test que puedes ejecutar en menos de cinco minutos, la mayoría desde un navegador o un solo comando de terminal. Imprime el resumen del final y pégalo al lado de tu monitor.


Por Qué Existe Este Checklist

Un fundador con el que trabajé lanzó su MVP vibe-coded un jueves. Para el sábado por la noche le habían volcado la base de datos — cada email de usuario, cada registro, todo. Un atacante encontró el puerto de MongoDB expuesto, se conectó sin credenciales y exfiltró el contenido completo. El fundador había fallado en tres elementos de la lista que estás a punto de leer. Le llevó diez minutos ejecutar las comprobaciones después de la brecha. Le habría llevado diez minutos antes.

Construí la primera versión de este checklist en VULNEX tras presentar en una conferencia de seguridad en 2025, basándome en las vulnerabilidades que no dejaba de ver en código generado por IA. Desde entonces, el patrón no ha hecho más que empeorar. El informe de GitGuardian de 2026 encontró 28,65 millones de nuevos secretos filtrados en GitHub en 2025 — un aumento del 34% interanual. Los commits que involucran asistentes de programación con IA filtran secretos a más del doble de la tasa base. La investigación de Apiiro mostró que el código de IA añadía más de 10.000 nuevos hallazgos de seguridad al mes en los repositorios estudiados a mediados de 2025. Las brechas que cubrí en la Parte 3 — Moltbook, Enrichlead, aplicaciones comprometidas días después de su lanzamiento — todas fallaron en elementos de esta lista.

Esto no es un programa de seguridad completo. Son las quince cosas que, si las haces mal, garantizan que alguien encuentre el agujero antes que tú. Si las haces bien, estarás por delante de la gran mayoría de MVPs vibe-coded que se lanzan hoy.

Las comprobaciones están agrupadas en cinco áreas. Usaré QuickNote — la aplicación de notas deliberadamente vulnerable del resto de esta serie — y algunos otros ejemplos reales para hacer cada una concreta.


Área 1: El Perímetro

Lo que los atacantes ven en el momento en que apuntan un navegador o un escáner de puertos a tu aplicación.

Comprobación 1: Forzar HTTPS en todas las páginas

Las configuraciones de despliegue generadas por IA rutinariamente omiten HTTPS. El modelo te da una aplicación Node.js funcional escuchando en el puerto 3000 por HTTP plano — lo cual está bien para desarrollo local y es catastrófico en producción. Sin HTTPS, cada inicio de sesión, cada token de API, cada dato de usuario viaja por internet en texto plano. Cualquiera en la misma red — una cafetería, una oficina compartida, un ISP comprometido — puede leerlo.

Cómo comprobarlo:

curl -I http://tuapp.com

Quieres una redirección 301 o 308 a https://. Si obtienes un 200 en HTTP plano, tu aplicación está sirviendo contenido sin cifrar. Comprueba también que tu API responda solo por HTTPS — curl -I http://tuapp.com/api/notes debería redirigir, no devolver datos.

Cómo solucionarlo: Si estás en Vercel, Netlify o Cloudflare Pages, HTTPS se fuerza automáticamente. En un VPS o despliegue Docker, configura tu proxy inverso (Nginx, Caddy) para redirigir todo el HTTP a HTTPS. Caddy lo hace por defecto — una razón por la que lo recomiendo para fundadores que no quieren complicarse con certificados TLS.

Comprobación 2: Configurar cabeceras de seguridad

Abre securityheaders.com y escanea tu dominio. Si obtienes algo por debajo de una B, tienes trabajo por hacer. En toda la web, solo el 21,9% de los sitios despliegan una Content Security Policy — y las aplicaciones vibe-coded están muy por debajo de esa media porque la IA raramente genera configuración de cabeceras de seguridad a menos que lo pidas.

Cómo comprobarlo:

curl -I https://tuapp.com | grep -iE "strict-transport|content-security|x-frame|x-content-type"

Quieres ver al menos estas cuatro cabeceras en la respuesta: Strict-Transport-Security, Content-Security-Policy, X-Frame-Options y X-Content-Type-Options. Si no ves ninguna, tu aplicación tiene cero protección contra clickjacking, sniffing de MIME y ataques de degradación de protocolo.

Cómo solucionarlo: Añádelas en tu proxy inverso, tu middleware de Express o la configuración de tu plataforma de hosting. Un conjunto razonable para un MVP:

Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; script-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()

Ajusta Content-Security-Policy según lo que tu aplicación realmente carga — si usas un CDN para scripts, añade su dominio a script-src. Si tu aplicación deja de funcionar después de añadir CSP (habitual con aplicaciones React que usan scripts inline), empieza con script-src 'self' 'unsafe-inline' y refuerza después. Una CSP imperfecta es mejor que ninguna CSP.

Comprobación 3: Cerrar puertos expuestos y paneles de administración

Las guías de despliegue de IA a menudo dejan puertos de base de datos abiertos a internet. A principios de 2026, Shodan indexa más de 213.000 instancias de MongoDB expuestas — muchas sin autenticación requerida. Si usas Firebase, no asumas que estás a salvo: RedHunt Labs descubrió que 1 de cada 5 bases de datos de Firebase tenían reglas mal configuradas que permitían acceso público de lectura, exponiendo emails, contraseñas y mensajes privados. Tu base de datos nunca debería ser accesible desde internet — y «gestionada» no significa «asegurada.»

Cómo comprobarlo:

nmap -Pn -p 5432,27017,6379,3306,9200 tuapp.com

Eso escanea PostgreSQL (5432), MongoDB (27017), Redis (6379), MySQL (3306) y Elasticsearch (9200). Todos esos puertos deberían mostrar filtered o closed. Si alguno muestra open, tu base de datos es directamente accesible desde internet — y si usa credenciales por defecto o no tiene autenticación (como suele pasar con Redis), probablemente ya está comprometida.

Comprueba también los paneles de administración: navega a /admin, /dashboard, /supabase, /_next, /graphql, /phpmyadmin. Si alguno carga sin requerir autenticación desde internet, bloquéalo o elimínalo.

Cómo solucionarlo: Configura el firewall de tu proveedor de hosting para permitir conexiones a la base de datos solo desde la IP de tu servidor de aplicaciones. En AWS, eso es una regla de security group. En un VPS, usa ufw allow from <ip-app> to any port 5432. Para paneles de administración, ponlos detrás de autenticación o restringe el acceso por IP.


Área 2: Secretos

La categoría más común de vulnerabilidad en vibe coding. La IA genera código con secretos embebidos porque eso es lo que muestran los datos de entrenamiento — el código de tutoriales hardcodea credenciales por simplicidad, y el modelo reproduce el patrón.

Comprobación 4: Escanear tu código en busca de secretos hardcodeados

De los 28,65 millones de secretos filtrados en GitHub en 2025, una parte desproporcionada vino de código generado por IA. GitGuardian encontró que los commits que involucran un asistente de programación con IA filtraban secretos a una tasa del 3,2% — más del doble de la tasa base del 1,5% en GitHub público. El modelo pone tu clave de servicio de Supabase en una constante, tu clave secreta de Stripe en un objeto de configuración, tu cadena de conexión de base de datos en un archivo Docker Compose. Lo hace porque es lo que funciona, y el código funcional es para lo que optimiza. Imagina esto: un fundador sube una clave secreta de Stripe a un repositorio público a las 14:00. A las 16:00, los bots ya la han encontrado. A las 18:00, los cargos fraudulentos empiezan a llegar a su cuenta. Esto pasa todos los días — los datos de GitGuardian muestran que los secretos filtrados se explotan típicamente en cuestión de horas.

Cómo comprobarlo:

# Instalar y ejecutar Gitleaks en tu repositorio
gitleaks detect --source . --report-format json --report-path leaks.json

O usa TruffleHog para un escaneo más profundo incluyendo el historial de git:

trufflehog git file://. --json

Cualquier hallazgo son secretos que se han subido a tu repositorio. Aunque los elimines del código actual, están en tu historial de git — y si el repositorio fue público en algún momento, ya han sido extraídos.

Cómo solucionarlo: Rota cada secreto filtrado inmediatamente — no te limites a eliminarlo del código. Mueve todos los secretos a variables de entorno cargadas en tiempo de ejecución. Si estás en Vercel, Railway o Render, usa su interfaz de variables de entorno. Nunca pongas secretos en archivos .env que se suban a git. Lo que nos lleva a la siguiente comprobación.

Comprobación 5: Verificar que los archivos .env y las imágenes Docker no filtran secretos

Dos canales ocultos que la IA crea rutinariamente para la filtración de secretos. Primero: archivos .env. El modelo crea un .env con tus credenciales de base de datos pero no siempre lo añade a .gitignore. Segundo: imágenes Docker. Como cubrí en la Parte 5, los Dockerfiles generados por IA a menudo insertan secretos en la build con instrucciones ARG y ENV, haciéndolos visibles en el historial de capas de la imagen.

Cómo comprobarlo:

# Comprobar si .env está en tu gitignore
grep "\.env" .gitignore

# Comprobar si algún archivo .env está siendo rastreado por git
git ls-files | grep -i "\.env"

# Comprobar la imagen Docker en busca de secretos filtrados
docker history --no-trunc tuapp:latest | grep -iE "key|secret|password|token"

Si git ls-files muestra algún archivo .env, ese archivo — y cada secreto en él — está en el historial de tu repositorio. Si docker history muestra credenciales, cualquiera que descargue tu imagen puede extraerlas.

Cómo solucionarlo: Añade .env* a .gitignore antes de tu primer commit. Para Docker, usa builds multi-stage y pasa los secretos como variables de entorno en tiempo de ejecución, nunca como argumentos de build. Si ya hay secretos en el historial de git, necesitas usar git filter-repo para purgarlos — y rotar cada secreto expuesto.

Comprobación 6: Bloquear CORS

Los errores de configuración de Cross-Origin Resource Sharing están por todas partes en las aplicaciones vibe-coded. Los problemas de CORS se sitúan de forma consistente entre las vulnerabilidades de aplicaciones web más comunes, y las aplicaciones vibe-coded son especialmente propensas porque la configuración típica de Express.js generada por IA incluye cors() sin argumentos — lo que por defecto usa Access-Control-Allow-Origin: *, permitiendo que cualquier sitio web en internet haga peticiones autenticadas a tu API.

Cómo comprobarlo:

curl -H "Origin: https://evil.com" -I https://tuapp.com/api/notes

Mira la cabecera Access-Control-Allow-Origin en la respuesta. Si dice * o refleja https://evil.com, tu API servirá datos felizmente a cualquier sitio web que pregunte — incluyendo una página de phishing de un atacante.

Cómo solucionarlo: Configura CORS para permitir solo tus propios dominios:

app.use(cors({
  origin: ['https://tuapp.com', 'https://www.tuapp.com'],
  credentials: true
}));

Nunca uses origin: true (refleja cualquier origen) ni dejes CORS con el wildcard por defecto en producción.


Área 3: Autenticación y Acceso

Aquí es donde las aplicaciones vibe-coded fallan más estrepitosamente. La IA construye autenticación que funciona — puedes iniciar sesión, ves tus datos — pero se salta los controles que impiden que todos los demás también vean tus datos. Cubrí los detalles en la Parte 5, pero aquí tienes cómo comprobar los fallos críticos.

Comprobación 7: Añadir rate limiting al login y registro

Sin rate limiting, tu endpoint de login acepta intentos de contraseña ilimitados. El credential stuffing — ataques automatizados usando pares de usuario/contraseña filtrados de otras brechas — genera 26.000 millones de intentos al mes a nivel global. Microsoft Entra bloquea 7.000 ataques de contraseña por segundo. Si tu login no tiene rate limit, un atacante puede probar miles de contraseñas por minuto contra las cuentas de tus usuarios.

QuickNote tenía exactamente esta vulnerabilidad. Sin rate limiter en /api/login, un atacante podía hacer fuerza bruta sobre la contraseña de cualquier cuenta a la velocidad de su conexión a internet.

Cómo comprobarlo:

# Enviar 20 peticiones rápidas a tu endpoint de login
for i in $(seq 1 20); do
  curl -s -o /dev/null -w "%{http_code}\n" \
    -X POST https://tuapp.com/api/login \
    -H "Content-Type: application/json" \
    -d '{"email":"test@test.com","password":"wrong"}';
done

Si las 20 devuelven 401 (credenciales inválidas) sin ningún 429 (demasiadas peticiones), no tienes rate limiting. Deberías empezar a ver respuestas 429 después de 5-10 intentos.

Cómo solucionarlo: En Express.js, añade express-rate-limit:

const loginLimiter = rateLimit({
  windowMs: 60 * 1000,
  max: 5,
  message: { error: 'Too many attempts, try again later' }
});
app.post('/api/login', loginLimiter, loginHandler);

Aplica rate limiting a los endpoints de registro y recuperación de contraseña también — se atacan con la misma frecuencia.

Comprobación 8: Verificar que cada endpoint de API comprueba la autenticación

Las APIs generadas por IA a menudo tienen autenticación en algunos endpoints pero no en otros. El modelo construye un flujo de login, genera un token, y luego se olvida de comprobar ese token en la mitad de las rutas. He revisado aplicaciones vibe-coded donde /api/login estaba correctamente protegido pero /api/users, /api/notes y /api/admin aceptaban peticiones sin autenticar.

Cómo comprobarlo:

# Intenta acceder a tus endpoints de API sin token de autenticación
curl -s https://tuapp.com/api/notes
curl -s https://tuapp.com/api/users
curl -s https://tuapp.com/api/settings

Cada endpoint protegido debería devolver 401 Unauthorized cuando se llama sin un token válido. Si alguno devuelve datos, ese endpoint es públicamente accesible para cualquiera que conozca la URL.

Cómo solucionarlo: Añade middleware de autenticación que se ejecute en cada ruta por defecto, y luego exime explícitamente solo las rutas públicas (login, registro, health check). En Express.js:

// Eximir rutas públicas ANTES del middleware de auth
app.post('/api/login', loginHandler);
app.post('/api/signup', signupHandler);

// Luego aplicar middleware de auth a todo lo demás bajo /api
app.use('/api', authMiddleware);

Comprobación 9: Comprobar que los usuarios solo acceden a sus propios datos

Esta es la vulnerabilidad IDOR — Insecure Direct Object Reference — y es el fallo más peligroso en aplicaciones vibe-coded multiusuario. La aplicación funciona correctamente cuando la usas normalmente: ves tus notas, tus facturas, tu perfil. Pero si cambias el ID en la URL o en la petición a la API, ves los datos de otra persona. QuickNote tenía esto: cambiar /api/notes/42 por /api/notes/43 devolvía las notas privadas de otro usuario. Sin comprobación de propiedad, sin autorización — solo una consulta a la base de datos por ID.

Cómo comprobarlo:

# Inicia sesión como usuario A, obtén su token, y anota el ID de un recurso que le pertenece
# Luego intenta acceder a un recurso que pertenece al usuario B
curl -H "Authorization: Bearer <token-usuario-a>" \
  https://tuapp.com/api/notes/9999

Si esto devuelve datos (en vez de 403 Forbidden), cualquier usuario autenticado puede acceder a los datos de cualquier otro usuario adivinando o incrementando IDs. Si tu aplicación usa IDs enteros auto-incrementales, un atacante puede enumerar cada registro de tu base de datos.

Cómo solucionarlo: Añade una cláusula WHERE user_id = authenticated_user_id a cada consulta de base de datos. Si estás en Supabase, habilita Row Level Security y crea políticas:

CREATE POLICY notes_owner ON notes
  USING (user_id = auth.uid());

Prueba la política iniciando sesión como dos usuarios diferentes y verificando que ninguno puede ver los datos del otro.


Área 4: Manejo de Datos

Cómo tu aplicación procesa lo que los usuarios le envían. El código generado por IA es optimista por defecto — asume que toda la entrada está bien formada y es de confianza. Los atacantes no envían entradas bien formadas.

Comprobación 10: Validar toda la entrada en el servidor

Si tu aplicación tiene un formulario, prueba qué pasa cuando pones <script>alert('xss')</script> en cada campo de texto. Si tu aplicación tiene búsqueda, prueba '; DROP TABLE users; --. El código generado por IA casi nunca valida la entrada en el servidor a menos que lo pidas específicamente. La validación del lado del cliente (atributos HTML required, comprobaciones JavaScript) se elude trivialmente — abre las herramientas de desarrollo del navegador y elimina la validación, o envía peticiones directamente con curl.

Imagina que has construido una aplicación de facturación para freelancers con IA. El campo «nombre de empresa» en el formulario de factura probablemente acepta cualquier cadena. Un atacante pone una etiqueta de script en el nombre de empresa, genera una factura, y cuando tu cliente abre esa factura en PDF o vista web — el script se ejecuta en su navegador, potencialmente robando su sesión.

Cómo comprobarlo:

# Probar XSS en un campo de texto
curl -X POST https://tuapp.com/api/notes \
  -H "Authorization: Bearer 
<token>" \
  -H "Content-Type: application/json" \
  -d '{"title":"<script>alert(1)</script>","content":"test"}'

# Probar inyección SQL en un parámetro de búsqueda
curl "https://tuapp.com/api/search?q=test%27%20OR%201=1--"

Si la etiqueta de script se almacena y se renderiza de vuelta sin escapar, tienes XSS almacenado. Si la prueba de inyección SQL devuelve más datos de los esperados, tienes inyección SQL.

Cómo solucionarlo: Valida y sanitiza toda la entrada en el servidor. Usa una librería de validación como Zod o Joi en Node.js. Define qué debe aceptar cada campo — tipo de dato, longitud máxima, conjunto de caracteres — y rechaza cualquier cosa que no coincida. Sanitiza HTML con una librería como DOMPurify antes de renderizar contenido generado por usuarios.

Comprobación 11: Usar consultas parametrizadas

Esta es la defensa del servidor contra la inyección SQL. Las consultas con concatenación de cadenas — donde la entrada del usuario se pega directamente en la cadena SQL — son una de las vulnerabilidades más antiguas y peligrosas del desarrollo web. La IA las genera regularmente porque los datos de entrenamiento están llenos de ellas.

Cómo comprobarlo:

# Buscar concatenación de cadenas en SQL en tu código
grep -rn "query.*\`.*\${" ./src/
grep -rn "query.*+.*req\." ./src/
grep -rn "f\".*SELECT" ./src/

Cualquier coincidencia es una potencial vulnerabilidad de inyección SQL. El patrón query(\SELECT FROM notes WHERE id = ${noteId}`)es vulnerable. El patrónquery(‘SELECT FROM notes WHERE id = $1′, [noteId])` es seguro.

Cómo solucionarlo: Reemplaza cada consulta con concatenación de cadenas por consultas parametrizadas. En Node.js con pg:

// Vulnerable
db.query(`SELECT * FROM notes WHERE id = ${noteId}`);

// Seguro
db.query('SELECT * FROM notes WHERE id = $1', [noteId]);

Si usas un ORM como Prisma o Drizzle, estás generalmente a salvo por defecto — pero revisa si hay llamadas a $queryRawUnsafe o $executeRawUnsafe, que puentean las protecciones del ORM.

Comprobación 12: No almacenar tokens ni datos sensibles en localStorage

Esta es la vulnerabilidad que le da a un atacante control total de la cuenta a través de cualquier agujero XSS. localStorage es accesible por cada script que se ejecuta en tu página. Si un atacante encuentra cualquier forma de inyectar JavaScript — mediante un XSS almacenado en un campo de perfil de usuario, mediante un script de terceros comprometido, mediante una extensión del navegador — puede leer cada token en localStorage y enviarlo a su servidor.

QuickNote almacenaba tokens de acceso JWT en localStorage. Combinado con la falta de validación de entrada, esto significaba que cualquier vulnerabilidad XSS le daba a un atacante el token de autenticación de cada usuario.

Cómo comprobarlo:

Abre tu aplicación en el navegador, inicia sesión, y luego abre las Herramientas de Desarrollo (F12) → Aplicación → Local Storage. Si ves algo etiquetado como token, access_token, jwt, session o similar — eso es un hallazgo. Comprueba también sessionStorage.

Cómo solucionarlo: Almacena los tokens de autenticación en cookies httpOnly con los flags Secure y SameSite=Strict. Estas cookies son invisibles para JavaScript — el XSS no puede leerlas, y se envían automáticamente con cada petición a tu servidor. Esto es lo que produce por defecto el prompt orientado a seguridad de la Parte 7.


Área 5: Dependencias y Despliegue

Lo que lanzaste junto con tu propio código. Las herramientas de IA incorporan dependencias que nunca elegiste, generan configuraciones que nunca revisaste, y crean manejo de errores que le dice a los atacantes exactamente qué salió mal.

Comprobación 13: Auditar tus dependencias en busca de vulnerabilidades conocidas

Cada dependencia que tu herramienta de IA añadió es una superficie de ataque que no aceptaste conscientemente. El informe de Sonatype de 2026 documentó 454.648 nuevos paquetes maliciosos en 2025 — un aumento del 75% interanual. Tu asistente de programación con IA eligió paquetes basándose en la popularidad en los datos de entrenamiento, no en si han sido parcheados recientemente o si han sido marcados como maliciosos.

Cómo comprobarlo:

# Node.js
npm audit

# Python
pip-audit

# O usa Snyk para un informe más detallado
npx snyk test

npm audit viene integrado en Node.js y se ejecuta en segundos. Presta atención a los hallazgos de severidad high y critical. pip-audit hace lo mismo para Python. Para un análisis más profundo incluyendo dependencias transitivas y alcanzabilidad, Snyk y Endor Labs ofrecen planes gratuitos.

Cómo solucionarlo: Ejecuta npm audit fix para parches automáticos. Para vulnerabilidades que no se pueden corregir automáticamente, comprueba si una versión más reciente del paquete las resuelve, o busca un paquete alternativo. Cubrí el flujo completo de gestión de dependencias en la Parte 4.

Comprobación 14: Restringir la subida de archivos

Si tu aplicación acepta subida de archivos — fotos de perfil, documentos, adjuntos — prueba qué pasa cuando subes algo que no es lo que el formulario espera. La subida de archivos sin restricción es una clase de vulnerabilidad con CVSS 10.0. En abril de 2025, CVE-2025-31324 — una subida de archivos sin autenticación en SAP NetWeaver — fue explotada activamente para subir webshells y lograr ejecución remota de código completa. El mismo patrón aparece en aplicaciones vibe-coded: la IA genera un endpoint de subida que guarda lo que sea que recibe en el sistema de archivos, sin comprobación de tipo, sin límite de tamaño, sin sanitización del nombre de archivo.

Cómo comprobarlo: Intenta subir un archivo con extensión .html o .svg a través del formulario de subida de tu aplicación. Si se guarda y es accesible en una URL pública, intenta acceder a él en un navegador — si el HTML se renderiza o el SVG ejecuta JavaScript, tienes XSS almacenado vía subida de archivos. Prueba también a subir un archivo muy grande (100MB+) — si no hay límite de tamaño, eso es un vector de denegación de servicio.

Cómo solucionarlo: Valida el tipo de archivo en el servidor comprobando los magic bytes del archivo, no solo la extensión (las extensiones se pueden falsificar). Limita el tamaño del archivo. Almacena las subidas en un bucket de almacenamiento dedicado (S3, Cloudflare R2) con una sobreescritura de content-type que fuerce la descarga en vez de renderizar. Nunca sirvas archivos subidos por usuarios desde el mismo dominio que tu aplicación — usa un subdominio o dominio de CDN separado.

Comprobación 15: Asegurarse de que los errores no filtran detalles internos

El código generado por IA deja mensajes de error detallados en producción. Trazas de pila, cadenas de conexión de base de datos, rutas de archivos, versiones de paquetes — toda información que ayuda a un atacante a entender tu infraestructura y encontrar su siguiente exploit. El manejador de errores por defecto de Express.js, por ejemplo, envía la traza de pila completa al cliente en modo desarrollo — y el código generado por IA a menudo no cambia al modo de producción en el despliegue.

Cómo comprobarlo:

# Provocar un error solicitando un recurso que no existe
curl https://tuapp.com/api/notes/id-inexistente-999999

# Intentar enviar datos malformados
curl -X POST https://tuapp.com/api/notes \
  -H "Content-Type: application/json" \
  -d '{"json invalido'

Si la respuesta incluye una traza de pila, rutas de archivos (como /app/src/routes/notes.js:42), errores de base de datos (como relation "users" does not exist), o números de versión de frameworks — tu manejo de errores está filtrando información.

Cómo solucionarlo: Establece NODE_ENV=production en tu entorno de despliegue. Añade un manejador de errores global que capture todos los errores y devuelva un mensaje genérico al cliente mientras registra los detalles en el servidor:

app.use((err, req, res, next) => {
  console.error(err); // Registrado en el servidor, no enviado al cliente
  res.status(500).json({ error: 'Internal server error' });
});

El Checklist Imprimible

Imprímelo. Pégalo al lado de tu monitor. Recórrelo antes de cada despliegue. Descarga la versión PDF de una página si prefieres una impresión más limpia.

El Perímetro

  • 1. HTTPS forzado en todas las páginas — curl -I http://tuapp.com devuelve redirección 301/308
  • 2. Cabeceras de seguridad configuradas — puntuación B o superior en securityheaders.com
  • 3. Sin puertos de BD ni paneles de admin expuestos — nmap -p 5432,27017,6379 muestra filtered/closed

Secretos

  • 4. Sin secretos hardcodeados — gitleaks detect devuelve cero hallazgos
  • 5. .env excluido de git, sin secretos en capas Docker — git ls-files | grep .env no devuelve nada
  • 6. CORS bloqueado a tus dominios — curl -H "Origin: https://evil.com" no refleja el origen

Autenticación y Acceso

  • 7. Rate limiting en login/registro — 20 peticiones rápidas provocan respuestas 429
  • 8. Cada endpoint de API requiere autenticación — curl sin autenticar devuelve 401
  • 9. Los usuarios solo acceden a sus propios datos — prueba de ID cruzado devuelve 403

Manejo de Datos

  • 10. Validación de entrada en el servidor — etiquetas <script> rechazadas o escapadas
  • 11. Consultas parametrizadas — grep no encuentra SQL con concatenación de cadenas
  • 12. Sin tokens en localStorage — las herramientas de desarrollo no muestran tokens de auth en storage

Dependencias y Despliegue

  • 13. Dependencias auditadas — npm audit muestra cero hallazgos high/critical
  • 14. Subida de archivos restringida — tipo, tamaño y ubicación de almacenamiento validados
  • 15. Los errores no filtran detalles — peticiones malformadas devuelven mensajes genéricos, sin trazas de pila

Si solo puedes arreglar tres cosas hoy

Si has ejecutado el checklist y has fallado en varios puntos, aquí tienes por dónde empezar:

Primero: Comprobación 4 (secretos hardcodeados). Si Gitleaks ha encontrado secretos en tu repositorio, ya están filtrados. Cada minuto que esperas es un minuto que un atacante puede usar esas credenciales. Rótalos ahora — antes de arreglar cualquier otra cosa.

Segundo: Comprobación 9 (usuarios accediendo a datos de otros usuarios). Si tu prueba de IDOR ha fallado, cualquier usuario autenticado puede navegar por toda tu base de datos incrementando IDs. Esta es la vulnerabilidad que convierte un incidente de seguridad en una notificación de brecha de datos.

Tercero: Comprobación 1 (HTTPS). Sin HTTPS, cada corrección que apliques después puede ser interceptada en tránsito. HTTPS es la base — nada más funciona sin él.

Todo lo demás importa, pero estos tres son los puntos donde la distancia entre «vulnerable» y «comprometido» se mide en horas, no en semanas.


Lo Que Este Checklist No Cubre

Quince puntos no pueden cubrirlo todo. Este checklist es el suelo, no el techo. Algunas cosas que necesitarás más allá de esta lista cuando crezcas más allá del MVP:

Test de penetración. Una vez que tengas usuarios de pago, contrata a un profesional para que intente entrar. En VULNEX hacemos este tipo de trabajo regularmente, y puedo decirte que un pentest casi siempre encuentra cosas que ningún checklist detecta — fallos de lógica de negocio, condiciones de carrera, problemas en los límites de confianza que solo salen a la luz cuando un humano piensa como un atacante contra tu aplicación específica.

Logging y monitorización. La comprobación 7 te dice que añadas rate limiting, pero también necesitas saber cuándo alguien está sondeando tus defensas. Registra los intentos de autenticación, los patrones de acceso a datos y las tasas de error. Envía los logs a un servicio que pueda alertarte cuando los patrones cambien.

Cumplimiento normativo. Si manejas datos de salud (HIPAA), datos de tarjetas de pago (PCI DSS) o datos de usuarios europeos (RGPD), tienes requisitos regulatorios más allá de este checklist. No asumas que el código generado por IA cumple la normativa — compruébalo.

Escaneo automatizado. Este checklist es manual. Una vez que lo hayas pasado, configura escaneo de seguridad automatizado en tu pipeline de CI/CD — SAST, DAST, comprobaciones de dependencias en cada pull request. Cubrí por qué las aplicaciones vibe-coded necesitan configuraciones de escáner diferentes al código tradicional en la Parte 6.

Modelado de amenazas. La Parte 7 cubrió cómo construir un modelo de amenazas antes de escribir código. Si te saltaste ese paso, vuelve y hazlo ahora. El checklist detecta problemas comunes; un modelo de amenazas detecta los específicos de tu aplicación.


Lo Único Que Debes Recordar

Cada comprobación de esta lista existe porque he visto una aplicación vibe-coded fallar en ella en producción. No en teoría — en producción, con datos reales de usuarios expuestos. Las vulnerabilidades de QuickNote de esta serie, las brechas de la Parte 3, los fallos de autenticación de la Parte 5 — todos se mapean a elementos de esta lista.

La IA construyó tu aplicación. No la aseguró. Eso es tu trabajo, y este checklist es el mínimo. Ejecútalo antes del lanzamiento. Ejecútalo otra vez después de cada funcionalidad importante. Conviértelo en un hábito, y tu MVP vibe-coded será más seguro que la mayoría de las aplicaciones programadas tradicionalmente que audito.

Como siempre: no te fíes de nada, verifica todo.


Lecturas Recomendadas


Referencias

Publicado en AI, IA, Seguridad, Tecnologia | Etiquetado , , , , , | Deja un comentario

El Vacío de Estrategia de IA: Por Qué «Usamos ChatGPT» No Es un Plan

Tiempo de lectura: 18 minutos

TL;DR

Un CEO le dice al consejo que la empresa está «totalmente volcada en la IA». Tres plantas más abajo, esto es lo que significa de verdad: marketing tiene funcionando un chatbot del que seguridad nunca ha oído hablar, finanzas acaba de pegar las cifras trimestrales en una cuenta personal de ChatGPT, un desarrollador conectó la semana pasada un agente autónomo a la base de datos de producción, y RR. HH. está preparando una lista de puestos que recortar porque «ahora lo hace la IA». Eso no es una estrategia. Es una suscripción disfrazada de estrategia.

Una estrategia de IA de verdad tiene un responsable, talento propio, una plantilla que amplificas en vez de despedir, datos limpios por debajo, políticas que se pueden hacer cumplir, un plan de infraestructura y visibilidad sobre cada modelo y cada agente de tu red. La mayoría de las empresas en 2026 no tienen casi nada de esto. Tienen adopción sin gobernanza, herramientas sin dueño y agentes que nadie vigila.

Los números lo confirman. Alrededor del 88% de las organizaciones ya usan IA en al menos una función de negocio, pero solo una de cada cuatro tiene un marco de gobernanza real. Aproximadamente tres de cada cuatro planean adoptar IA agéntica en dos años, mientras que solo una de cada cinco puede gobernar los agentes que ya ejecuta. El 49% de los empleados usa herramientas de IA que su empresa nunca aprobó. Y solo el 7% dice que sus datos están realmente listos para la IA.

Esa brecha entre lo que las empresas usan y lo que de verdad controlan es el vacío de estrategia de IA. En mi experiencia tiene siete agujeros recurrentes. Vamos a verlos.


Una aclaración por delante. No estoy en contra de la IA y no vengo a convencer a nadie de que no la use. Yo trabajo con agentes de IA todos los días. El problema no es que las empresas usen IA. El problema es que «usamos IA» ha pasado a significar «tenemos una estrategia de IA», y son dos cosas muy distintas, tan distintas como tener un coche y saber conducir.

Agujero nº1: Nadie es Dueño de la IA — Falta el CAIO

Haz esta prueba en tu propia organización. ¿Quién es responsable, con nombre y apellidos, de la estrategia de IA, del riesgo de IA y del retorno de la inversión en IA? Si la respuesta honesta es «bueno, IT y el CISO y aquel director de marketing llevan cada uno una parte», entonces nadie es responsable. La responsabilidad compartida de algo tan grande suele significar que no la tiene nadie.

Por eso el Chief AI Officer (CAIO) se ha convertido en el puesto que más rápido crece en la alta dirección. IBM encuestó a 2.000 directores generales de todo el mundo para su estudio de 2026 y descubrió que el 76% afirma tener ya un CAIO, frente a apenas un 26% un año antes. Heineken, WPP, Nike y CVS Health han creado el rol. El beneficio también aparece en los datos: las empresas con un CAIO tienen casi 3 veces más probabilidades de alcanzar la máxima madurez en IA (Futurum) y obtienen un retorno notablemente mayor de su gasto en IA (IBM).

Pero ese 76% adorna la foto. Entre las grandes empresas, solo alrededor de una de cada cuatro tiene un CAIO realmente dedicado. Muchas de las demás le dieron a alguien el título y nada más: un «Head of AI» sin presupuesto, sin voz en las compras y sin autoridad para cancelar un proyecto malo.

Un CAIO que no puede vetar un despliegue temerario no es un dueño de la estrategia. Es una nota de prensa.

Y lo importante no es el organigrama. Es que, sin una persona responsable, las decisiones de IA acaban en manos de quien se mueve primero, que normalmente es un departamento pagando una herramienta con la tarjeta de la empresa. Nadie mide la velocidad frente al riesgo, nadie conecta el gasto en IA con los resultados, y nadie tiene una respuesta de verdad cuando el consejo pregunta cuál es la exposición. Y se nota: solo alrededor del 32% de las organizaciones tiene algún proceso formal para medir si sus inversiones en IA funcionan siquiera. La mayoría está escalando algo que ni siquiera sabe puntuar.

Así que nombra a alguien de verdad. Dale autoridad sobre la estrategia, el presupuesto, el riesgo y las compras, no solo la parte bonita de la «innovación», y un mandato que cruce IT, seguridad, legal, datos y las unidades de negocio. Exígele resultados y una cifra, porque el objetivo nunca fue «usamos IA», sino «la IA movió estas cifras». Y si eres demasiado pequeño para un CAIO dedicado, no pasa nada, pero nombra igualmente al responsable. El problema es la dispersión de la responsabilidad, no la plantilla.

Agujero nº2: No Hay Expertos en Casa — ¿Dónde Está tu AI Red Team?

Un CAIO sin equipo es un general sin ejército. El segundo agujero es la ausencia casi total de talento de IA propio, y es peor en el lado de la seguridad.

Cuando CIO.com preguntó a los CIO qué frenaba la IA en la empresa en su encuesta State of the CIO de 2026, la respuesta más repetida, con un 40%, fue la falta de talento interno. Otra encuesta de contratación de 2026 encontró que el 91% de las organizaciones prioriza la contratación de perfiles con conocimientos de IA, y que los ingenieros de IA (39%) son el puesto más difícil de cubrir, justo por delante de los ingenieros de ciberseguridad (38%).

La mayoría de los roles que faltan apenas existían hace tres años:

  • El AI Red Team, cuyo trabajo es romper tus propios modelos antes de que lo haga otro: jailbreaks, prompt injection, extracción de modelos, envenenamiento de datos, manipulación de agentes. Los portales de empleo listaban más de 2.500 ofertas activas de AI/ML security engineer en marzo de 2026.
  • Ingenieros de seguridad de IA para blindar la cadena, desde el supply chain del modelo y los servidores MCP hasta los permisos de los agentes y los endpoints de inferencia. Cerca del 32% de las organizaciones que contrataron los incorporaron en 2026.
  • Especialistas en seguridad de AI/ML (34%) y analistas de gobernanza de IA (30%), las personas que convierten la política en controles reales y en la evidencia que pedirá un auditor.

El informe de plantilla de Accenture de 2026 lo afina: por primera vez, la brecha de competencias superó a la falta de personal como principal problema de la plantilla de seguridad. No es solo que no tengas suficiente gente. Es que la que tienes se formó para un mundo anterior a la IA. Un administrador de firewalls que jamás ha visto un ataque de prompt injection no es tu AI Red Team.

Y esto no va solo de los especialistas. La alfabetización en IA en toda la plantilla es ya la base, no un extra, y en la UE es literalmente la ley: la obligación de alfabetización en IA del Reglamento de IA está en vigor desde febrero de 2025. IBM calcula que más de la mitad de los empleados necesita reciclarse solo para seguir haciendo bien su trabajo actual en un mundo con IA. Una estrategia que forma a una pequeña élite y deja al resto buscándose la vida es justo cómo nace la Shadow AI.

Ya he escrito antes sobre el AI Agent Skill Poisoning y sobre cómo convertir las skills de agentes en armas. Esos ataques son invisibles para un equipo que no tiene a nadie que entienda cómo funcionan los agentes por dentro. No puedes defender un modelo de amenaza que nunca has estudiado.

Así que monta una función estable de pruebas adversariales, aunque sea pequeña o externalizada, en lugar de una auditoría anual. Recicla a la gente de seguridad que ya tienes en amenazas específicas de IA; el OWASP Top 10 para LLM y su trabajo sobre amenazas agénticas son puntos de partida gratuitos. Contrata para el rol real cuando contrates, un ingeniero de seguridad de IA o un analista de gobernanza, no «IA» pegado a una descripción de puesto genérica de IT. Y pon un programa de alfabetización en IA de verdad delante de todos los demás. Trata el talento propio como un control, no como un lujo. Es lo único que separa la promesa de un proveedor de tu realidad.

Agujero nº3: Despedir Gente en Vez de Amplificarla

Este es el agujero que se celebra como estrategia en las notas de prensa y se convierte en una recontratación silenciosa seis meses después.

En 2026, las empresas no solo adoptan IA: la usan como excusa para recortar personas. Según Challenger, Gray & Christmas, la IA se citó en 87.714 recortes de empleo en EE. UU. hasta mayo de 2026, alrededor del 22% de todos los despidos del año — ya más que los 54.836 atribuidos a la IA en todo 2025, y en mayo se había convertido en el motivo más citado para los recortes. Salesforce dice que sus agentes de IA gestionan ya cerca de la mitad de las interacciones con clientes y ha «reequilibrado» la plantilla en consecuencia; Block está pasando de unos 10.000 empleados a 6.000.

El problema es que buena parte de esto es una apuesta por lo que la IA podría hacer, no por lo que ha hecho. Una encuesta de Harvard Business Review de finales de 2025 encontró que la mayoría de los directivos que recortaban por motivos de IA lo hacían basándose en el potencial esperado de la tecnología, no en su rendimiento demostrado. Y la factura ya está llegando: Forrester halló que el 55% de los empleadores se arrepiente de sus despidos motivados por la IA, y Gartner espera que para 2027 la mitad de las empresas que recortaron plantilla señalando a la IA vuelva a contratar para puestos similares — a menudo con otro título, a veces con menos sueldo.

El caso de manual es Klarna. Sustituyó a unos 700 empleados de atención al cliente por un asistente construido con OpenAI y presumió de que la IA gestionaba dos tercios de todos los tickets de soporte. Después la calidad y la confianza de los clientes se desplomaron, y el CEO admitió que la empresa había «ido demasiado lejos». Klarna está volviendo a contratar humanos. La lección que sacó todo el mundo es la misma: la IA debe aumentar a las personas, no reemplazarlas.

Este es el argumento que defendí en AI Must Make Superhumans, Not Unemployed. Como dijo Jensen Huang, las empresas con imaginación usan la IA para hacer más con más; las que se han quedado sin ideas solo la usan para hacer lo mismo con menos. Despedir para fabricarte una «estrategia de IA» tira por la borda lo único que el modelo no tiene, el contexto de tu gente: quiénes son los clientes, por qué existe el proceso, dónde están los problemas enterrados. Combina ese contexto humano con la IA y obtienes algo que ninguno de los dos logra por separado. Quítalo y te queda una forma más rápida de producir errores seguros de sí mismos y sin responsable.

Para ser justos, esto no significa que la plantilla nunca cambie de forma legítima. Hay puestos que se transforman y algunos se reducen de verdad a medida que el trabajo se automatiza, y eso puede ser lo correcto. El error es tomar esa decisión apostando por lo que la IA podría hacer, antes de haber demostrado que puede, y tirar por la borda el contexto que tu gente ha tardado años en acumular.

Una estrategia de verdad aquí es explícita al respecto. Decide, en voz alta, que la IA está para multiplicar la producción de tu gente, no para adelgazar las filas. Reinvierte el tiempo que la IA libera en trabajo de más valor, en lugar de tratarlo solo como un coste que extraer. Mantén a humanos en el bucle en todo lo que toque a clientes, dinero o juicio. Y desconfía profundamente de cualquier plan de «reemplazamos el equipo por agentes» que no haya contabilizado la recontratación, la confianza perdida y el conocimiento institucional saliendo por la puerta.

Agujero nº4: No Hay Base de Datos (Data Foundation)

Cada uno de los agujeros anteriores se apoya en este, y es el que nadie quiere mirar porque no es vistoso.

La IA funciona con tus datos, y los datos de la mayoría de las empresas son un desastre. Según un informe de 2026 de Cloudera y Harvard Business Review Analytic Services, solo el 7% de las empresas dice que sus datos están completamente listos para la IA, y otras investigaciones lo dicen más claro: alrededor del 93% no tiene datos listos para IA, y solo en torno al 30% tiene una gobernanza de datos adecuada. Casi el 80% de las organizaciones dice que los problemas de acceso a los datos están frenando activamente su IA.

Por eso tanta IA no llega a salir del laboratorio. En torno al 80% de los proyectos de IA no llega a producción, casi el doble que los proyectos de IT normales, y Gartner espera que el 60% de los proyectos de IA sin datos listos para IA se abandone a lo largo de 2026. El modelo casi nunca es el problema. Lo es el dato que lo alimenta: fragmentado entre sistemas, sin documentar, sin gobernar, lleno de duplicados y huecos, e imposible de rastrear.

Hay también una dimensión de seguridad, y es la que muerde en silencio. Si no sabes dónde viven tus datos sensibles, no puedes mantenerlos fuera de los prompts. Cada fuga de Shadow AI y cada agente con permisos de más de los agujeros siguientes es, en el fondo, un fallo de gobernanza de datos. No puedes proteger lo que no has clasificado.

Una base de datos sólida no es glamurosa, pero es el trabajo que hace que todo lo demás dé fruto. Saber qué datos tienes y clasificarlos por sensibilidad. Arreglar la propiedad, la calidad y el linaje para poder responder «de dónde viene esto» sobre cualquier cosa que toque una IA. Ponerle controles de acceso y reglas de retención antes de apuntarle un modelo. Las empresas que obtienen retornos reales de la IA no suelen ser las de los modelos más ingeniosos. Son las que hicieron primero este trabajo aburrido.

Agujero nº5: No Hay Políticas de IA — Uso, Privacidad y la Lista Negra Que Falta

Este es el agujero más barato de cerrar y el que más a menudo se deja abierto.

Los números no animan. Solo el 38% de las empresas estadounidenses ha publicado una política de IA. Casi un tercio no tiene ninguna política de gobernanza de IA, y otra cuarta parte sigue «implementándola». El 78% de los directivos no confía con firmeza en poder superar una auditoría independiente de gobernanza de IA en 90 días (Grant Thornton, 2026). En el lado de la seguridad es aún peor: según los datos de Salesforce de 2026, el 67% de los empleados ya usa IA en el trabajo, pero solo el 18% de las organizaciones tiene una política formal de seguridad de IA.

Un marco de políticas real no es un memorándum de una página pidiendo «ser responsables». Es un puñado de documentos que se pueden hacer cumplir de verdad:

  • Una política de uso aceptable que diga qué herramientas están aprobadas, para qué y en qué condiciones. Cursor para prototipar, vale. Pegar código fuente en una cuenta personal de ChatGPT, no.
  • Una política de datos y privacidad que nombre las clases de datos que jamás deben tocar un sistema de IA: PII de clientes, datos de salud, información financiera, secretos, cualquier cosa regulada. Esto es lo que evita que tus datos de clientes y tu código fuente se filtren a herramientas cualquiera.
  • Una lista de herramientas aprobadas y una lista negra. Casi todo el mundo olvida la lista negra. Necesitas una lista explícita y mantenida de herramientas y modelos prohibidos: las apps de consumo sin validar, las que tienen condiciones hostiles de retención de datos, las extensiones de navegador que se comunican a escondidas, cualquier cosa autoalojada sin autenticación. Una lista negra le da a tu DLP y a tu proxy algo concreto que bloquear.
  • Gobernanza de proveedores y modelos que cubra residencia de datos, retención, el derecho a auditar y si tus datos entrenan su modelo.
  • Gestión de incidentes y excepciones: cómo se solicita una herramienta nueva y qué pasa cuando alguien se salta las reglas.

Si operas en Europa o vendes a Europa, una parte de esto ya no es opcional. El Reglamento de IA de la UE (AI Act) ya está parcialmente en vigor: las prohibiciones de ciertas prácticas y el deber de alfabetización en IA aplican desde febrero de 2025, las normas para modelos de IA de propósito general desde agosto de 2025, y una fecha de cumplimiento importante cae el 2 de agosto de 2026, con multas de hasta el 7% de la facturación global para las peores infracciones. Las obligaciones de alto riesgo se aplazaron a finales de 2027 y a 2028 con el Digital Omnibus, pero «ya lo veremos» no es un plan cuando los relojes de la alfabetización y la transparencia ya están corriendo.

Y no es solo Bruselas. Los Estados miembros están añadiendo sus propias leyes nacionales por encima. España, sin ir más lejos, aprobó en mayo de 2026 el Proyecto de Ley Orgánica para el Buen Uso y la Gobernanza de la IA, que ahora avanza por el Parlamento. Refuerza las normas de la UE con un régimen sancionador propio (hasta 35 millones de euros o el 7% de la facturación global), la obligación de etiquetar deepfakes y contenido generado por IA, y un supervisor nacional, la AESIA, con sede en A Coruña, que tiene plenas potestades sancionadoras desde agosto de 2025 y opera un sandbox regulatorio al que las empresas pueden solicitar acceso. Estados Unidos, en cambio, no tiene una ley federal única, sino un mosaico de leyes estatales que se multiplica a toda velocidad. La conclusión práctica: «¿qué leyes de IA nos aplican, en cada mercado en el que operamos?» es ya una pregunta que tu estrategia tiene que responder, no una hipótesis que aparcar para más adelante.

Aquí está la trampa de la política por sí sola: el 46% de los usuarios de Shadow AI dice que seguiría usando sus herramientas aunque la empresa las prohibiera expresamente. Una política que vive en un PDF que nadie lee es teatro. Para que sirva, hay que cablearla en los proxies, el DLP, el SSO y los controles de consentimiento OAuth. Escribe las políticas básicas, mantenlas cortas y concretas, conecta cada regla a un control que la haga cumplir, mantén la lista negra como un documento vivo y dale a la gente una vía rápida al «sí», porque cuando la aprobación tarda tres semanas, te esquivan.

Agujero nº6: No Hay Estrategia de Hardware — IA Local y Soberana

La mayoría de las «estrategias de IA» tienen forma de API. Todo corre en las GPU de otro, en la jurisdicción de otro y bajo las condiciones de otro. Eso vale para una demo. Para datos regulados, propiedad intelectual y riesgo geopolítico es una vulnerabilidad, y significa que no hay ningún plan de infraestructura.

Esta la aprendí por las malas. Cuando Anthropic bloqueó el uso de las suscripciones de Claude en agentes de terceros a principios de este año, todo mi montaje de agentes quedó de repente a merced de una decisión de precios en la que yo no había pintado nada. La solución fue ser dueño de una parte mayor de mi propia infraestructura. La misma lógica escala: si toda tu capacidad de IA puede apagarse o encarecerse por decisión de un proveedor un viernes por la tarde, eso no es una estrategia, es una dependencia.

2026 es el año en que la IA soberana y local dejó de ser cosa de nicho, y el dinero lo deja claro. McKinsey ya dimensiona la IA soberana como un mercado de 500.000 a 600.000 millones de dólares para 2030. Los propios ingresos de IA soberana de NVIDIA se triplicaron con creces hasta superar los 30.000 millones en el ejercicio fiscal 2026. El gasto europeo en infraestructura de nube soberana se prevé en torno a 12.600 millones de dólares este año, un salto del 83%, además de los 20.000 millones de euros destinados a gigafábricas de IA dentro del impulso más amplio de 200.000 millones de InvestAI. Gartner hasta acuñó una palabra para la migración inversa, geopatriación: sacar datos y cargas de trabajo de las nubes públicas globales y devolverlos a entornos locales o soberanos para gestionar el riesgo regulatorio y geopolítico.

El argumento para ser dueño de parte de tu propio cómputo se reduce a cuatro cosas. La residencia de datos y el cumplimiento se vuelven más fáciles cuando los datos nunca salen de tus paredes ni de tu jurisdicción. Tus prompts, tus ajustes finos y tus modelos propietarios siguen siendo tuyos en lugar de acabar en el set de entrenamiento de un tercero. Los costes se convierten en un capex predecible para cargas estables y de alto volumen, en lugar de un opex por token que sube con el uso. Y dejas de estar a una caída, una subida de precio o un cambio de política de quedarte sin capacidad de IA de un día para otro.

Pero aquí hay un filo afilado. Hacer esto sin estrategia es exactamente como se crea el lío de Shadow AI de la siguiente sección. Un equipo de investigación que se compra un NVIDIA DGX Spark de 4.000 dólares, lo enchufa a la red y ejecuta Ollama escuchando en 0.0.0.0 sin autenticación no ha construido IA soberana. Ha construido una superficie de ataque expuesta. En febrero de 2026, los investigadores encontraron más de 10.000 instancias de Ollama accesibles desde internet abierto, una de cada cuatro con una versión vulnerable, y muchas de ellas alojando modelos corporativos privados. La IA local hecha a propósito es un activo. La IA local hecha en la sombra es una brecha esperando su fecha de divulgación.

Así que decide tus niveles a conciencia: qué cargas pueden ir en model-as-a-service público, cuáles necesitan una nube soberana o regional y cuáles tienen que correr on-premise, en función de lo sensibles que sean los datos. Planifica un recorrido largo, porque estas migraciones tardan de tres a cuatro años, y la parte lenta es organizativa, no técnica. Haz pasar todo el hardware de IA por compras, con aprobación de IT, segmentación de red y un escaneo de seguridad antes de que toque la red. Y protege los modelos privados como la propiedad intelectual que son.

Agujero nº7: No Hay Visibilidad Agéntica — La Shadow AI Que No Ves

No puedes gobernar lo que no ves, y con los agentes la mayoría de las empresas van a ciegas.

Entré a fondo en la mecánica de esto en Las Dos Amenazas Gemelas en la Sombra: Cuando Shadow AI y Vibe Coding Se Descontrolan en Tu Red, la convergencia de infraestructura de IA no autorizada (Shadow AI) y aplicaciones creadas por IA sin revisar (Shadow Vibe Coding). En resumen: modelos invisibles masticando tus datos más sensibles, aplicaciones sin validar llenas de fallos y ningún registro con el que reconstruir nada. Las organizaciones con un uso intenso de Shadow AI afrontan costes de brecha de media de 4,63 millones de dólares, unos 670.000 más por incidente que las que lo mantienen bajo control.

Pon agentes autónomos encima de eso y el problema de visibilidad empeora mucho. Según la investigación de Strata de 2026 sobre identidad de agentes, cerca del 80% de las organizaciones que ejecutan IA autónoma no pueden decirte en tiempo real qué están haciendo esos sistemas ni quién es responsable de ellos. Solo el 21% mantiene un inventario en tiempo real de los agentes activos, y solo el 28% puede rastrear las acciones de un agente hasta un responsable humano. La mayoría sigue autenticando a los agentes con claves de API compartidas; apenas el 22% los trata como identidades distintas. Y el dato que más me alarma: una amplia mayoría de directivos confía en que sus políticas actuales cubren las acciones no autorizadas de los agentes, mientras que sobre el terreno más de la mitad de los agentes desplegados funcionan sin ninguna supervisión de seguridad ni registro.

Ese contraste es el problema entero en miniatura. La dirección cree que hay una estrategia. La red dice lo contrario. Gartner espera que, para finales de 2027, más del 40% de los proyectos de IA agéntica se cancelen, a menudo porque los problemas de gobernanza solo salen a la luz después de que algo ya se ha roto en producción.

Conviene recordar qué es de verdad un agente: software que actúa en tu nombre. Lee datos, llama a APIs, mueve dinero, escribe y despliega código y, cada vez más, habla con otros agentes, normalmente con credenciales permanentes y poca supervisión. Un agente que no ves, que no puedes inventariar y que no puedes rastrear hasta un dueño es, en la práctica, un empleado con acceso a los sistemas y sin jefe.

La salida empieza por el descubrimiento, no por la política. Saca los dominios de IA de tus logs de DNS y proxy, revisa los consentimientos de apps OAuth en Entra ID y Google Workspace, escanea en busca de puertos de IA expuestos (11434 para Ollama, 1234 para LM Studio) y lanza una encuesta anónima para averiguar qué usa la gente de verdad. Luego construye un inventario vivo de agentes donde cada uno tenga identidad propia, dueño, permisos acotados y registro, y retira las claves compartidas. Haz que cada acción de un agente sea rastreable hasta un responsable humano, porque las auditorías y la respuesta a incidentes dependen de ello. Y aplica el mínimo privilegio y la monitorización a estas identidades no humanas igual que harías con tu personal, porque están actuando en tu nombre.

«¿Pero Esto No Nos Va a Frenar?»

Es la objeción que más oigo, normalmente de quien ahora mismo está pagando herramientas de IA con la tarjeta de la empresa. Merece tomarse en serio, porque el miedo es real: la gobernanza puede convertirse perfectamente en un comité que dice que no a todo y no entrega nada.

Pero los datos apuntan en sentido contrario. En la encuesta de Grant Thornton de 2026, las organizaciones con IA plenamente integrada y bien gobernada eran las más seguras de poder superar una auditoría y obtenían mejores retornos, no peores. No es casualidad. La gobernanza es lo que te permite decir que sí rápido y con seguridad, porque hay una lista de herramientas aprobadas, una política de datos y un responsable que puede decidir. Las empresas que se sienten «frenadas» por la gobernanza suelen ser las que se la pegan encima después de un incidente, como limpieza, en vez de construirla desde el principio como un carril rápido.

Velocidad y control no son opuestos aquí. La marcha atrás de Klarna, los proyectos de IA abandonados, las divulgaciones de brechas: eso es lo que te frena. Una estrategia es cómo vas rápido sin estrellarte contra el muro.

El Patrón: Adopción Sin Estrategia

Da un paso atrás y los siete agujeros son en realidad un mismo fallo con siete disfraces:

Lo que las empresas tienen Lo que exige una estrategia
Licencias de ChatGPT y Copilot Un responsable con nombre que rinda cuentas del riesgo y el ROI de la IA (CAIO)
Promesas de proveedores Talento propio, un AI Red Team capaz de verificarlas
Notas de prensa de despidos Una plantilla amplificada por la IA, no reemplazada por ella
Datos dispersos en silos Una base de datos gobernada y lista para IA
Un memorándum de «ser responsables» Políticas de uso, privacidad y lista negra que se hacen cumplir
Todo en las GPU de otro Un plan deliberado de infraestructura local y soberana
Confianza en que está «controlado» Visibilidad en tiempo real de cada modelo y cada agente

El hilo conductor es que cerca de nueve de cada diez empresas han adoptado IA mientras que solo una de cada cuatro ha construido la gobernanza que le corresponde. Compraron la herramienta y se saltaron la estrategia.

Nada de esto va contra la IA. Si acaso, va a favor. La IA es demasiado potente y está demasiado metida en el trabajo regulado como para seguir gestionándola como lo hace hoy la mayoría: a salto de mata, sin dueño, sin monitorizar y sin documentar. Las empresas que ganen esta década no serán las que adoptaron más rápido. Serán las que la gobernaron lo bastante bien como para escalarla con seguridad.

Por Dónde Empezar

Siete agujeros son muchos a la vez, así que no intentes taparlos todos de golpe. El orden importa más que la velocidad.

  1. Nombra al responsable. Nada más se ordena hasta que alguien rinde cuentas. La primera semana, no el próximo trimestre.
  2. Descubre lo que ya tienes. Antes de escribir una sola política, encuentra la Shadow AI: revisa los logs de DNS y proxy, los consentimientos OAuth, escanea puertos de IA expuestos y lanza una encuesta anónima. Gobiernas la realidad, no un deseo.
  3. Escribe las políticas y conéctalas a controles. Uso aceptable, datos y privacidad, lista negra. Cortas, concretas, aplicadas y conscientes del AI Act si Europa entra en juego.
  4. Arregla la base de datos en paralelo. Clasifica y gobierna los datos que tocarán tus modelos. Esto es lento, así que empiézalo pronto y déjalo correr junto a todo lo demás.
  5. Construye el talento y la alfabetización. Un pequeño red team, personal de seguridad con criterio en IA y un programa de alfabetización para todos los demás.
  6. Planifica la infraestructura. Decide tus niveles público/soberano/on-premise y pon bajo control las compras de hardware.
  7. Consigue visibilidad de agentes y mantenla. Un inventario vivo, identidades distintas, trazabilidad hasta un humano. Esto no «termina» nunca.

Y por debajo de todo: trata la IA como una forma de hacer superhumana a tu gente, no de hacerla prescindible. Eso es una postura, no un proyecto, y tiñe cada decisión de arriba.

En Resumen

«Usamos ChatGPT» responde a la pregunta equivocada. La de verdad es si puedes nombrar quién es el dueño de tu IA, demostrar que está haciendo mejor a tu gente en vez de simplemente reducirla, y sacar un inventario en vivo de cada modelo y cada agente de tu red. Si no puedes responder a eso, no tienes una estrategia de IA. Tienes una suscripción de IA y un montón de riesgo que crece en silencio.

La buena noticia es que ninguno de estos siete agujeros es exótico. Son el trabajo poco glamuroso y perfectamente factible de la gobernanza, y las empresas que lo hacen son las que seguirán en pie cuando la primera oleada de incidentes de gobernanza de IA llegue a los titulares.

La aplicación montada en veinte minutos, el agente que nadie inventarió, el equipo despedido en favor de un bot que se recontrata en silencio seis meses después: esas son las historias con moraleja del mañana. La estrategia es lo que mantiene a tu empresa fuera de la próxima.

Lecturas Adicionales:

Publicado en AI, Economia, IA, Privacidad, Seguridad, Tecnologia | Etiquetado , , , , , | Deja un comentario

Prompt Engineering para Código Seguro (Parte 7)

Serie Seguridad del Vibe Coding

  1. ¿Qué es la Seguridad del Vibe Coding? Una Guía de Campo para 2026
  2. El OWASP Top 10 para Aplicaciones Vibe-Coded
  3. Anatomía de una Brecha de Vibe Coding: Lecciones de los Peores Incidentes de 2026
  4. La Trampa de las Dependencias: Riesgos en la Cadena de Suministro del Código Generado por IA
  5. Autenticación y Secretos: Lo Que la IA Siempre Hace Mal
  6. Escaneando Aplicaciones Vibe-Coded: Por Qué el SAST/DAST Tradicional Se Queda Corto
  7. Prompt Engineering para Código Seguro (estás aquí)
  8. El Checklist de Seguridad del Fundador
  9. Asegurando el Pipeline de Codificación IA
  10. El Futuro de la Seguridad del Vibe Coding

Tiempo de lectura: 21 minutos

TL;DR

Los modelos de IA ya saben escribir código seguro — identifican el 78,7% de sus propias vulnerabilidades cuando se les pide que revisen. El problema es que no aplican ese conocimiento por defecto. Cinco estrategias de prompting cierran esa brecha: role-setting, reverse prompting, prompting orientado a modelo de amenazas, restricciones negativas y reparación iterativa. Los prompts de seguridad dirigidos reducen las vulnerabilidades hasta un 56%. Este artículo cubre qué funciona, qué no, y cómo hacer permanentes las instrucciones de seguridad mediante archivos de instrucciones.


La Brecha Entre Lo Que la IA Sabe y Lo Que la IA Hace

Este es el hallazgo más importante en seguridad de código IA de este año. Un estudio de abril de 2026 verificó formalmente 3.500 artefactos de código en siete LLMs usando el solver SMT Z3. Los resultados: el 55,8% de los artefactos contenían al menos una vulnerabilidad verificada. GPT-4o fue el peor con un 62,4% vulnerable. Gemini 2.5 Flash fue el mejor con un 48,4%. Ningún modelo obtuvo más que un aprobado raspado.

Pero el estudio tenía un segundo hallazgo que lo cambia todo. Cuando los investigadores pidieron a los mismos modelos que revisaran su propia salida en busca de vulnerabilidades, los modelos identificaron correctamente los problemas el 78,7% de las veces. El modelo que acababa de escribir una inyección SQL podía explicar por qué era peligrosa y cómo arreglarla — cuando se le preguntaba.

Los investigadores lo llaman la «asimetría generación-revisión.» Yo lo llamo la brecha entre lo que la IA sabe y lo que la IA hace. El modelo tiene el conocimiento de seguridad. Simplemente no lo activa durante la generación. Los prompts por defecto optimizan para la funcionalidad — «hazme una página de login» te da una página de login que funciona. Si es segura o no es una preocupación secundaria que el modelo no considera a menos que se lo digas.

Esta asimetría es exactamente lo que el prompt engineering explota. No estás enseñando al modelo algo nuevo. Estás activando conocimiento que ya tiene.

La línea base es mala. El análisis de CodeRabbit de 470 pull requests reales encontró que el código generado por IA tiene una densidad de vulnerabilidades 2,74 veces mayor que el código escrito por humanos, con 1,4 veces más problemas de seguridad críticos. Veracode probó más de 100 LLMs y encontró que no previenen XSS en el 86% de los casos de prueba. A mediados de 2025, el análisis de Apiiro de miles de repositorios mostró que el código IA añadía más de 10.000 nuevos hallazgos de seguridad al mes — un aumento de 10 veces respecto a seis meses antes.

La brecha es real. La pregunta es si el prompting puede cerrarla.


Por Qué «Escribe Código Seguro» No Funciona

El enfoque intuitivo — añadir «asegúrate de que el código sea seguro» a tu prompt — no hace gran cosa. Un estudio de 2026 ejecutó pruebas chi-cuadrado sobre código generado con y sin prefijos de seguridad simples y no encontró mejora estadísticamente significativa en varias configuraciones. Peor aún, un enfoque de Chain-of-Thought con conocimiento de debilidades — donde el prompt listaba tipos específicos de vulnerabilidad a evitar — no logró reducir las vulnerabilidades de forma estadísticamente significativa, y en algunas configuraciones los números en realidad subieron. Los investigadores encontraron que sobrecargar el prompt con preocupaciones de seguridad cambiaba principalmente qué tipos de vulnerabilidad aparecían en vez de reducir el total, y puede degradar la capacidad del modelo para generar código funcional, introduciendo errores que crean nuevas superficies de ataque.

Las instrucciones de seguridad genéricas fallan por la misma razón que las instrucciones de código genéricas fallan. «Escribe buen código» produce la misma salida que no dar instrucciones. El modelo necesita concreción: qué amenazas aplican a esta funcionalidad, qué patrones evitar, qué controles de seguridad implementar, y en qué orden.

Bruni et al. (febrero de 2025) mostraron lo que ocurre cuando eres específico. Sus benchmarks en GPT-3.5-turbo, GPT-4o y GPT-4o-mini encontraron que los prefijos de prompt orientados a seguridad — los que nombraban clases específicas de vulnerabilidad y describían patrones defensivos concretos — redujeron las vulnerabilidades hasta un 56%. El prompting iterativo, donde alimentas los hallazgos de vulnerabilidades de vuelta al modelo y le pides que repare su propia salida, corrigió entre el 41,9% y el 68,7% de los problemas.

La conclusión: la especificidad importa más que la intención. «Sé seguro» no hace nada. «Este endpoint debe validar que el usuario autenticado es propietario del recurso solicitado antes de devolver datos, y debe devolver 403 si la verificación de propiedad falla» cambia la salida.


Cinco Estrategias Que Funcionan

No son teóricas. Uso variaciones de las cinco en VULNEX cuando trabajo con herramientas de codificación IA, y las dos primeras — role-setting y reverse prompting — son la columna vertebral de cómo abordo cada encargo.

Estrategia 1: Role-Setting

Antes de pedir a una IA que escriba o revise código, establezco su rol explícitamente. No un vago «eres útil» — una identidad profesional específica que activa la experiencia del dominio.

Para generación de código:

«Eres un desarrollador senior con años de experiencia construyendo productos seguros. Sigues las mejores prácticas de seguridad por defecto: validación de entrada, consultas parametrizadas, controles adecuados de autenticación y autorización, gestión segura de secretos y defensa en profundidad.»

Para revisión de seguridad:

«Eres un pentester senior y experto en ciberseguridad. Tu trabajo es encontrar cada vulnerabilidad, mala configuración y debilidad de seguridad en este código. Piensa como un atacante. Reporta lo que encuentres con niveles de gravedad y guía de remediación.»

La clave es un rol por tarea. Cuando construyes, el modelo piensa como un desarrollador consciente de la seguridad. Cuando revisa, piensa como un atacante. Mezclar los dos diluye ambos. Un desarrollador preocupándose por ataques mientras escribe código produce implementaciones defensivas pero frágiles. Un atacante revisando código mientras piensa en funcionalidad se pierde vulnerabilidades que entran en conflicto con los requisitos funcionales.

El role-setting funciona porque los LLMs ajustan su distribución de salida según la persona que se les asigna. Un prompt de «pentester senior» activa patrones que el modelo aprendió de investigación de seguridad, informes de vulnerabilidades y documentación de pruebas de penetración. Un prompt de «desarrollador junior» — o ningún rol — activa patrones de respuestas de Stack Overflow y código de tutoriales, que es de donde vienen la mayoría de los valores por defecto inseguros.

Estrategia 2: Reverse Prompting

La mayoría de la gente usa las herramientas de codificación IA en una dirección: «Constrúyeme X.» El reverse prompting le da la vuelta. En vez de decirle al modelo qué construir, le haces preguntas — y lo haces en ambas direcciones.

Antes de escribir código, interrogo al modelo sobre el espacio del problema:

«Necesito construir una API multi-tenant donde los usuarios solo puedan acceder a sus propios datos. Antes de escribir código: ¿cuáles son los principales riesgos de seguridad para este tipo de sistema? ¿Qué modelo de autenticación y autorización debería usar? ¿Cuáles son los errores comunes que cometen los desarrolladores con el aislamiento de datos multi-tenant?»

Las respuestas del modelo suelen ser excelentes — recuerda, identifica el 78,7% de las vulnerabilidades en modo revisión. Al pedirle que piense en amenazas antes de generar código, cargas ese conocimiento de seguridad en el contexto de generación. El código que escribe después está informado por el análisis de amenazas que acaba de producir.

Después de generar código, cuestiono la salida:

«Revisa el código que acabas de escribir. ¿Qué vulnerabilidades tiene? ¿Cómo evitaría un atacante la autenticación? ¿Qué casos límite podrían provocar fugas de datos? ¿Qué le falta a esta implementación que necesitaría un sistema en producción?»

Esto explota la asimetría generación-revisión directamente. El modelo generó código con algunos puntos ciegos de seguridad. Ahora le estás pidiendo que active el modo revisión sobre su propia salida. Señalará problemas que acaba de introducir — no todos, pero un porcentaje sustancial.

El enfoque bidireccional crea un bucle de retroalimentación. Las preguntas pre-código dan forma a lo que el modelo entiende como importante. Las preguntas post-código detectan lo que se escapó. Juntas, estrechan la brecha entre lo que el modelo sabe y lo que produce.

Estrategia 3: Prompting Orientado a Modelo de Amenazas

Esto se basa en el reverse prompting pero hace explícito el modelo de amenazas en la propia solicitud de código. En vez de pedir al modelo que genere una funcionalidad y esperar que considere la seguridad, describes el panorama de amenazas como parte del prompt.

Sin contexto de amenazas:

«Construye un endpoint REST API que permita a los usuarios actualizar su información de perfil.»

Con contexto de amenazas:

«Construye un endpoint REST API que permita a los usuarios actualizar su información de perfil. Es una aplicación SaaS multi-tenant. Asume que los atacantes intentarán: IDOR (acceder a perfiles de otros usuarios cambiando el ID), escalada de privilegios (modificar campos de rol o permisos), asignación masiva (enviar campos que la API no debería aceptar como isAdmin), e inyección a través de campos de perfil mostrados a otros usuarios. El endpoint debe validar la propiedad, usar una whitelist de campos permitidos, sanitizar toda la entrada y registrar los intentos de modificación.»

El mismo modelo, la misma tarea — pero el segundo prompt produce código con verificaciones de autorización, whitelist de campos, sanitización de entrada y registro de auditoría que el primer prompt casi seguro omite. El modelo no aprendió nada nuevo entre los dos prompts. El contexto de amenazas activó patrones de seguridad que ya tenía.

Para las clases de vulnerabilidad que he cubierto a lo largo de esta serie — los controles de auth ausentes de la Parte 5, los puntos ciegos arquitectónicos de la Parte 6 — el prompting orientado a modelo de amenazas es la prevención más directa. Le estás diciendo al modelo exactamente qué puede salir mal antes de que escriba una sola línea.

Estrategia 4: Restricciones Negativas

Los modelos de IA siguen las prohibiciones con más consistencia que las indicaciones abiertas. «Sé seguro» es vago. «NO hagas estas cosas específicas» es concreto y verificable.

«Construye el sistema de autenticación para esta aplicación Express.js. Restricciones:

  • NO almacenes tokens en localStorage (usa cookies httpOnly)
  • NO uses MD5 o SHA-1 para hashear contraseñas (usa bcrypt con factor de coste 12+)
  • NO saltes la validación de entrada del lado del servidor aunque exista validación en el cliente
  • NO hardcodees API keys, credenciales de base de datos o secretos en ningún lugar del código
  • NO configures CORS para permitir todos los orígenes
  • NO deshabilites Supabase RLS ni las reglas de seguridad de Firebase
  • NO crees tokens JWT sin tiempo de expiración»

Esto funciona porque las restricciones son binarias — el modelo las cumplió o no. Puedes verificar el cumplimiento mecánicamente. Y las restricciones apuntan directamente a los patrones que he documentado a lo largo de esta serie: los tokens en localStorage de la Parte 5, el RLS deshabilitado del ejemplo QuickNote, los secretos hardcodeados que SAST no siempre detecta.

Construye tu lista de restricciones a partir de tu propio historial de vulnerabilidades. Cada problema de seguridad que hayas encontrado en código generado por IA se convierte en un «NO» para futuros prompts. Con el tiempo, tu lista de restricciones se convierte en una política de seguridad en negativo — la imagen inversa de cada error que la IA ha cometido.

Estrategia 5: Reparación Iterativa

Esta es la única estrategia con benchmarks directos. Bruni et al. probaron generar código, escanearlo, alimentar los resultados del escaneo de vuelta al modelo y pedir reparaciones. Las mejores configuraciones repararon entre el 41,9% y el 68,7% de las vulnerabilidades.

El flujo de trabajo práctico:

  1. Genera código con tu herramienta de IA
  2. Ejecuta Semgrep: semgrep --config=p/security-audit --json ./src > findings.json
  3. Devuelve los hallazgos: «Aquí están los hallazgos de seguridad de Semgrep para el código que acabas de escribir. Corrige cada problema. Para cada corrección, explica cuál era la vulnerabilidad y por qué tu corrección la resuelve.»
  4. Ejecuta Semgrep de nuevo sobre la salida
  5. Repite hasta que esté limpio o haya rendimientos decrecientes

Combinar esto con role-setting amplifica el efecto. En vez de «corrige estos hallazgos,» prueba: «Eres un ingeniero de seguridad senior. Aquí están los hallazgos de Semgrep de una revisión de código. Para cada hallazgo, determina si es un verdadero positivo o un falso positivo. Para los verdaderos positivos, proporciona la corrección. Para los falsos positivos, explica por qué la alerta es incorrecta.»

La distinción de falsos positivos importa. Como cubrí en la Parte 6, las herramientas SAST marcan el 68-75% del código seguro como vulnerable. Hacer que el modelo filtre el ruido antes de actuar produce mejores reparaciones que corregir ciegamente cada alerta.


Haciéndolo Permanente: Archivos de Instrucciones

Las cinco estrategias anteriores funcionan en conversación. Pero nadie reescribe un modelo de amenazas y una lista de restricciones para cada prompt. La respuesta práctica son los archivos de instrucciones — prompts de seguridad permanentes que se aplican a cada interacción con tu herramienta de codificación IA.

Claude Code

Claude Code soporta un plugin de guía de seguridad que revisa código en tres niveles: coincidencia de patrones por edición (sin llamada al modelo, coste cero), revisión del diff al final de cada turno, y una revisión agéntica más profunda en cada commit. Se configura mediante un archivo .claude/claude-security-guidance.md que describe tu modelo de amenazas en lenguaje natural. El plugin detecta inyección, deserialización insegura y vulnerabilidades DOM antes de que lleguen a un pull request — el revisor se ejecuta como una llamada separada al modelo con contexto limpio, así que no está evaluando su propio trabajo.

Más allá del plugin, Claude Code lee instrucciones a nivel de proyecto desde archivos CLAUDE.md. Puedes integrar tu role-setting, restricciones y modelo de amenazas directamente:

# Requisitos de Seguridad

Eres un desarrollador senior construyendo una aplicación SaaS multi-tenant.
Cada endpoint de API DEBE:
- Verificar autenticación (JWT válido con comprobación de expiración)
- Verificar autorización (el usuario es propietario del recurso solicitado)
- Validar y sanitizar toda la entrada
- Devolver 403 para acceso no autorizado, no 404
- Registrar intentos de acceso para operaciones sensibles de seguridad

NO:
- Almacenar secretos en variables de entorno integradas en imágenes Docker
- Usar localStorage para tokens de autenticación
- Deshabilitar RLS en ninguna tabla de Supabase
- Crear endpoints sin limitación de peticiones

GitHub Copilot

Copilot lee desde copilot-instructions.md en el directorio .github, con soporte para archivos *.instructions.md con ámbito por ruta. La comunidad ha construido conjuntos de reglas alineados con OWASP con más de 55 anti-patrones y listas de bloqueo de «No Sugerir» que cubren eval(), SQL inline, deserialización insegura y más. El repositorio github/awesome-copilot tiene una plantilla lista para usar.

Reglas de Seguridad Multi-Herramienta

SecureCodeWarrior publica archivos de reglas de seguridad de código abierto compatibles con Copilot, Cursor, Windsurf y otros asistentes de IA. Robotti.io mantiene conjuntos de reglas personalizables para Java, Node.js, C# y Python que bloquean patrones arriesgados a nivel de IDE. Trail of Bits publicó skills de Claude Code para flujos de seguridad incluyendo integración con CodeQL y SARIF.

El paso práctico: elige el formato de archivo de instrucciones para tu herramienta de codificación IA principal, empieza con uno de los conjuntos de reglas de seguridad de código abierto, y personalízalo con tus propias restricciones. Cada «NO» de la Estrategia 4 pertenece a este archivo. Cada lección de una revisión de seguridad se convierte en una instrucción permanente.


La Superficie de Ataque Que Acabas de Crear

Los archivos de instrucciones son potentes, lo que los convierte en un objetivo. Si alguien puede modificar tu archivo de instrucciones, controla lo que la IA genera para todo tu proyecto.

El ataque Rules File Backdoor (CVE-2025-53773), divulgado por Pillar Security en marzo de 2025, demostró exactamente esto. Los investigadores incrustaron caracteres Unicode ocultos — marcadores de texto bidireccional y uniones de ancho cero — dentro de archivos de configuración de Copilot y Cursor. Estos caracteres invisibles contenían instrucciones que manipulaban la generación de código de la IA: inyectando puertas traseras, deshabilitando controles de seguridad, exfiltrando datos a través del código generado. El archivo de configuración parecía limpio para los revisores humanos. La IA leía las instrucciones ocultas y las seguía.

Trail of Bits demostró ataques de inyección de prompt logrando ejecución remota de código en tres plataformas de agentes. VentureBeat reportó en 2026 que tres agentes de codificación IA filtraron secretos a través de una única inyección de prompt. La superficie de ataque no es teórica.

La defensa es directa: trata los archivos de instrucciones como código. Revísalos en pull requests. Audítalos buscando caracteres ocultos (cat -v muestra caracteres de control, file muestra codificaciones inusuales). Ponlos bajo control de versiones. No aceptes archivos de instrucciones de fuentes no confiables — una plantilla de proyecto compartida con un .github/copilot-instructions.md envenenado es el ataque a la cadena de suministro de software adaptado a la era de la IA.


Poniéndolo Todo Junto: Un Flujo de Trabajo Completo

Las cinco estrategias no son cinco técnicas separadas — son etapas de un pipeline. Así es como lo abordo en VULNEX cuando construyo o reviso código generado por IA.

Paso 1: Establece el rol. Antes de nada, define la identidad del LLM. Para construir: desarrollador senior con experiencia en seguridad. Para revisar: pentester senior.

Paso 2: Reverse-prompt sobre el problema. Antes de escribir código, pregunta al modelo sobre el panorama de seguridad. «¿Cuáles son los principales riesgos para esta funcionalidad?» «¿Qué modelo de autenticación encaja en este caso de uso?» «¿Qué errores cometen habitualmente los desarrolladores aquí?» Usa las respuestas para informar tu solicitud de código.

Visualizar el modelo de amenazas. Puedes llevar el Paso 2 más lejos pidiendo al modelo que produzca un modelo de amenazas formal que puedas renderizar como diagrama. En VULNEX construimos usecvislib, una librería de visualización de seguridad de código abierto que genera modelos de amenazas STRIDE, árboles de ataque y otros diagramas de seguridad a partir de archivos de configuración TOML. El prompt pasa a ser:

«Basándote en los riesgos de seguridad que identificaste, genera un modelo de amenazas STRIDE para esta aplicación en formato TOML de usecvislib. Incluye externals, processes, datastores, dataflows, trust boundaries y threats con vectores CVSS 3.1.»

El modelo produce algo como esto (recortado por brevedad):

[model]
name = "QuickNote Threat Model"
description = "STRIDE threat model for note-taking SaaS"
type = "Threat Model"

[externals.user]
label = "User"
description = "Authenticated app user"

[externals.attacker]
label = "Attacker"
description = "Unauthenticated malicious actor"

[processes.api_server]
label = "API Server"
description = "Express.js REST API"

[processes.auth_service]
label = "Auth Service"
description = "Supabase Auth"

[datastores.postgres]
label = "PostgreSQL"
description = "Supabase DB with RLS policies"

[dataflows.login]
from = "user"
to = "api_server"
label = "Login Request"

[dataflows.note_query]
from = "api_server"
to = "postgres"
label = "Note Query"

[boundaries.internet]
label = "Internet"
elements = ["user", "attacker"]

[boundaries.backend]
label = "Backend Services"
elements = ["auth_service", "postgres"]

[threats.brute_force]
element = "api_server"
threat = "No rate limiting on /api/login enables brute force"
mitigation = "Rate limit to 5 attempts/minute per IP"
cvss_vector = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"

[threats.idor_notes]
element = "note_query"
threat = "User modifies note ID to access other users' data"
mitigation = "Verify resource ownership before returning data"
cvss_vector = "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N"

[threats.token_theft]
element = "login"
threat = "localStorage token accessible to injected scripts"
mitigation = "Store tokens in httpOnly secure cookies"
cvss_vector = "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N"

[threats.disabled_rls]
element = "postgres"
threat = "RLS policies disabled, no row-level access control"
mitigation = "Enable RLS, test policies with different tenant contexts"
cvss_vector = "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"

Después renderízalo: usecvis -m 1 -i quicknote_threat.toml -o quicknote_threats -f png -r. Obtienes un diagrama de flujo de datos con fronteras de confianza, amenazas puntuadas por CVSS y severidad codificada por colores — un artefacto visual que hace los riesgos de seguridad concretos para todo el equipo:

quicknote_threat_model

El flag -r también genera un informe de amenazas escrito. Las amenazas que el modelo identificó en este diagrama se convierten en las restricciones exactas que introduces en el siguiente paso.

Paso 3: Escribe el prompt con contexto de amenazas y restricciones. Combina el prompting orientado a modelo de amenazas con restricciones negativas. Describe qué estás construyendo, qué amenazas aplican y qué el código no debe hacer.

Paso 4: Reverse-prompt sobre la salida. Después de que el modelo genere código, pasa a modo revisión. «¿Qué vulnerabilidades tiene esto?» «¿Cómo evitarías esta verificación de auth?» «¿Qué falta?» Devuelve la propia crítica del modelo a la siguiente iteración.

Paso 5: Ejecuta escaneos automatizados e itera. Semgrep, npm audit, el pipeline de la Parte 6. Alimenta los hallazgos de vuelta al modelo con rol de ingeniero de seguridad. Repara, re-escanea, repite.

Paso 6: Codifica las lecciones como instrucciones permanentes. Cada vulnerabilidad que encuentres — a través de reverse prompting, escaneo automatizado o revisión manual — se convierte en una restricción en tu archivo de instrucciones. El archivo de instrucciones crece con cada proyecto, capturando el conocimiento de seguridad de tu equipo en una forma que la IA aplica automáticamente.

Para hacerlo concreto, aquí va un antes/después usando el endpoint de login de QuickNote (Parte 5).

Prompt ingenuo:

«Construye un endpoint de login para mi aplicación Express.js con Supabase.»

Esto es lo que produjo las vulnerabilidades de QuickNote: sin limitación de peticiones, sin expiración de token, credenciales en variables de entorno integradas en la imagen Docker, RLS deshabilitado. Aquí va una salida representativa:

// Salida del prompt ingenuo — login típico generado por IA
app.post('/api/login', async (req, res) => {
  const { email, password } = req.body;
  const { data, error } = await supabase.auth.signInWithPassword({
    email, password
  });
  if (error) return res.status(401).json({ error: 'Invalid credentials' });
  res.json({ token: data.session.access_token, user: data.user });
});

Sin limitación de peticiones — un atacante puede probar miles de contraseñas por minuto. El token va directo al cuerpo de la respuesta, donde el frontend lo almacena en localStorage (accesible a cualquier XSS). Sin validación de entrada. Sin comprobación de expiración del token. Las credenciales de Supabase integradas en la imagen Docker en tiempo de build. Esto es lo que el modelo genera por defecto.

Prompt con seguridad (usando el pipeline):

«Eres un desarrollador senior con años de experiencia construyendo sistemas de autenticación seguros. Construye un endpoint de login para una aplicación Express.js usando Supabase. Este endpoint será accesible públicamente en internet. Asume que los atacantes intentarán ataques de fuerza bruta, credential stuffing y robo de tokens. El endpoint DEBE: limitar los intentos de login (máximo 5 por minuto por IP), usar bcrypt para verificación de contraseñas, devolver tokens JWT con expiración de 1 hora establecida mediante expiresIn, almacenar tokens en cookies httpOnly secure (no en localStorage), validar toda la entrada del lado del servidor. NO hardcodees ningún secreto — usa variables de entorno cargadas solo en tiempo de ejecución. NO deshabilites Supabase RLS en ninguna tabla. Después de generar el código, lista cualquier preocupación de seguridad pendiente que deba abordar.»

Mismo modelo, misma tarea — diferente salida:

// Salida del prompt con seguridad — mismo modelo, misma tarea
const loginLimiter = rateLimit({
  windowMs: 60 * 1000, max: 5,
  message: { error: 'Too many login attempts, try again later' }
});

app.post('/api/login', loginLimiter, async (req, res) => {
  const { email, password } = req.body;

  // Validación de entrada del lado del servidor
  if (!email || typeof email !== 'string' || !email.includes('@')) {
    return res.status(400).json({ error: 'Valid email required' });
  }
  if (!password || typeof password !== 'string' || password.length < 8) {
    return res.status(400).json({ error: 'Invalid password format' });
  }

  const { data, error } = await supabase.auth.signInWithPassword({
    email: email.trim().toLowerCase(),
    password
  });
  if (error) {
    logger.warn('Failed login attempt', { email, ip: req.ip });
    return res.status(401).json({ error: 'Invalid credentials' });
  }

  // Token en cookie httpOnly, no en el cuerpo de la respuesta
  res.cookie('session', data.session.access_token, {
    httpOnly: true, secure: true, sameSite: 'strict',
    maxAge: 3600000 // 1 hora
  });
  res.json({ user: { id: data.user.id, email: data.user.email } });
});

Limitación de peticiones. Validación de entrada. Token en cookie httpOnly, no en el cuerpo de la respuesta. Intentos fallidos registrados. Email normalizado. El modelo no aprendió nada nuevo entre los dos prompts — el prompt con seguridad activó lo que ya sabía.


El Checklist de Prompt Engineering

  1. Establece un rol profesional específico antes de cada tarea de generación o revisión de código — «desarrollador senior» para construir, «pentester senior» para revisar
  2. Haz reverse-prompt antes de codificar: pide al modelo que identifique riesgos de seguridad, recomiende modelos de auth y señale errores comunes para tu funcionalidad específica
  3. Incluye contexto de amenazas en cada solicitud de código: nombra las amenazas (IDOR, XSS, inyección, fuerza bruta) y especifica la superficie de ataque (API pública, multi-tenant, maneja pagos)
  4. Añade restricciones negativas para las trampas conocidas de tu stack: «NO uses localStorage para tokens,» «NO deshabilites RLS,» «NO saltes la validación del lado del servidor»
  5. Haz reverse-prompt después de la generación: pide al modelo que revise su propia salida como pentester y liste qué falta o es vulnerable
  6. Ejecuta Semgrep y devuelve los hallazgos con rol de ingeniero de seguridad — no digas solo «corrige esto,» pide que distinga verdaderos positivos de falsos positivos
  7. Crea un archivo de instrucciones (.claude/claude-security-guidance.md, .github/copilot-instructions.md, o equivalente) con tus restricciones de seguridad permanentes
  8. Empieza con un conjunto de reglas de seguridad de código abierto (SecureCodeWarrior, Robotti.io, skills de Trail of Bits) y personalízalo
  9. Audita los archivos de instrucciones buscando caracteres ocultos y trátalos como código crítico de seguridad en control de versiones
  10. Añade cada vulnerabilidad que descubras a tu lista de restricciones — tu archivo de instrucciones debe crecer con cada proyecto y cada revisión de seguridad

Si No Haces Nada Más

Diez puntos de checklist y un pipeline de seis pasos puede parecer mucho cuando eres un fundador en solitario sacando una funcionalidad a medianoche. Esto es lo mínimo: establece un rol y añade tres restricciones.

«Eres un desarrollador senior construyendo una aplicación web segura. Construye [tu funcionalidad]. NO almacenes tokens en localStorage. NO saltes la validación de entrada del lado del servidor. NO hardcodees secretos.»

Eso es todo. Una frase de role-setting más tres restricciones «NO» adaptadas a tu stack. Se tarda diez segundos en escribir y cubre las vulnerabilidades que veo con más frecuencia en aplicaciones vibe-coded. Añade el paso de reverse prompting cuando tengas tiempo — pide al modelo que revise su propia salida como pentester. Solo con estos dos movimientos se cierra una cantidad sorprendente de la brecha.

Sobre la longitud del prompt: hay un punto de rendimientos decrecientes. El estudio de Kharma mostró que sobrecargar un prompt con preocupaciones de seguridad puede degradar la calidad del código funcional — el modelo intenta satisfacer demasiadas restricciones a la vez e introduce errores de lógica. En la práctica, mantengo los prompts de seguridad por debajo de un párrafo para solicitudes de código individuales. Si necesitas más de cinco o seis restricciones, es señal de que deberías moverlas a un archivo de instrucciones donde se apliquen automáticamente en vez de meterlas todas en cada prompt.


Lo Que Deberías Sacar de Esto

El prompt engineering para seguridad no consiste en engañar al modelo para que sea cuidadoso. Se trata de activar conocimiento que el modelo ya tiene. La asimetría generación-revisión — 55,8% de salida vulnerable, 78,7% de detección en revisión — nos dice que el conocimiento de seguridad está ahí. El prompt por defecto simplemente no lo pide.

Las cinco estrategias de este artículo cierran esa brecha desde distintos ángulos. El role-setting activa la experiencia del dominio. El reverse prompting obliga al modelo a pensar en amenazas antes y después de la generación. El prompting orientado a modelo de amenazas da al modelo el contexto que necesita para tomar decisiones arquitectónicas seguras. Las restricciones negativas previenen los errores específicos que ya has visto. La reparación iterativa detecta lo que se escapó.

Nada de esto reemplaza la revisión manual que describí en la Parte 6. Un modelo bien dirigido sigue fallando en aproximadamente el 20% de sus propias vulnerabilidades en modo revisión, y los problemas arquitectónicos como la lógica de autorización rota requieren juicio humano. Pero un modelo bien dirigido produce código que es mediblemente más seguro — hasta un 56% menos de vulnerabilidades — y eso reduce la brecha que la revisión manual necesita cubrir.

Mi flujo de trabajo en VULNEX: rol primero, preguntas segundo, código con restricciones tercero, revisión cuarto, escaneo quinto, y codificar todo lo que aprendo en archivos de instrucciones que hacen que el siguiente proyecto arranque desde una línea base más fuerte. El archivo de instrucciones es el interés compuesto del conocimiento de seguridad — cada encargo hace que el siguiente sea más seguro por defecto.

Como siempre: no te fíes de nada, verifica todo.


Lecturas Adicionales


Referencias

Publicado en AI, IA, Seguridad, Tecnologia | Etiquetado , , , , | Deja un comentario