El código generado por IA funciona. Se ejecuta. Se ve bien. También viene con las mismas cinco vulnerabilidades de seguridad en casi todos los proyectos. Estos no son riesgos teóricos — son los agujeros específicos que aparecen en casi todos los códigos producidos por Claude, Cursor, Replit o Copilot cuando no pides explícitamente seguridad.

He auditado docenas de proyectos vibe-coded en el último año, y los mismos cinco errores aparecen en al menos el 80% de ellos. Cada uno tarda menos de 30 minutos en repararse. Aquí está lo que debes buscar y exactamente cómo solucionarlo.

Datos rápidos
Para quién es esto
Cualquiera que envíe código generado por IA a usuarios o clientes
Tiempo para reparar los 5
1–3 horas dependiendo de la complejidad
Stack asumido
Next.js/React + Supabase/Firebase + Vercel/Netlify
Severidad
Los errores #1 y #2 pueden exponer datos de usuarios — repáralos primero
Última verificación
Abril de 2026

Error 1: Claves API Hardcodeadas en Código Frontend

Cómo sucede: Le dices a Claude "conecta a Supabase" o "agrega pagos con Stripe", y genera código con la clave API pegada directamente en un componente React. El código funciona perfectamente — y tu clave secreta es visible para cualquiera que abra DevTools del navegador y revise la pestaña Network o el código fuente de JavaScript.

Por qué es peligroso: Tu clave service role de Supabase omite toda la seguridad de la base de datos. Tu clave secreta de Stripe permite a alguien cobrar tarjetas o emitir reembolsos. Tu clave OpenAI permite a alguien acumular miles en llamadas API en tu cuenta. Los bots escanean activamente repositorios públicos de GitHub y sitios desplegados buscando claves expuestas.

La solución: Mueve cada secreto a variables de entorno. En Next.js, solo las variables que comienzan con NEXT_PUBLIC_ llegan al navegador. Cualquier clave que otorgue acceso de escritura, acceso de administrador o acceso financiero debe ser solo del lado del servidor.

Después de mover las claves a .env.local, busca en toda tu base de código los valores de clave antiguos para asegurarte de que desaparecieron. Luego revisa tu historial de Git — si la clave fue alguna vez comprometida, sigue en tu historial de repositorio incluso si la eliminaste. Regenera (rota) cualquier clave que haya sido expuesta, aunque sea brevemente.

Tiempo para reparar: 15–30 minutos.

Error 2: Tablas de Supabase Sin Row-Level Security

Cómo sucede: IA genera consultas de creación de tablas de Supabase y operaciones CRUD, pero no habilita Row-Level Security (RLS). Por defecto, las tablas de Supabase con RLS deshabilitada son completamente accesibles para cualquiera con tu URL de proyecto y clave anon — ambas son públicas (y deberían serlo).

Por qué es peligroso: Sin RLS, el Usuario A puede consultar los datos del Usuario B. Una simple llamada fetch desde la consola del navegador puede extraer todas las filas de cada tabla. Tu base de datos completa es efectivamente pública.

Cómo identificarlo: Ve a tu panel de Supabase → Table Editor. Si alguna tabla muestra "RLS Disabled", tienes este problema. También verifica si tu código del lado del cliente usa la clave service_role en lugar de la clave anon — eso es aún peor.

La solución: Habilita RLS en cada tabla. Luego crea políticas que se adapten a los patrones de acceso de tu aplicación. La política más común: los usuarios solo pueden SELECT, INSERT, UPDATE y DELETE filas donde auth.uid() = user_id. Prueba iniciando sesión como un usuario e intentando acceder a los datos de otro usuario a través de la API REST de Supabase.

Tiempo para reparar: 30–60 minutos dependiendo del número de tablas.

¿Obteniendo valor de esto? Publicamos un análisis profundo cada semana sobre herramientas de IA, flujos de trabajo y guías de seguridad prácticas. Únete a los lectores que se enteran primero →

Error 3: Sin Validación de Entrada en Formularios o Rutas API

Cómo sucede: IA genera formularios que aceptan cualquier entrada y rutas API que confían en cualquier dato que entra. El formulario tiene un atributo "required" en HTML, pero sin validación del lado del servidor. Alguien omite el formulario completamente enviando una solicitud API directa con cualquier payload que quiera.

Por qué es peligroso: Sin validación del lado del servidor, los atacantes pueden inyectar scripts en tu base de datos (XSS almacenado), enviar payloads demasiado grandes que causen un bloqueo del servidor, o enviar datos que rompan la lógica de tu aplicación (como un precio negativo o un campo de correo electrónico que contenga SQL).

Cómo identificarlo: Abre cualquier ruta API o server action en tu base de código. Si usa req.body o datos de formulario sin verificar la forma, tipo y longitud de cada campo, tienes este problema.

La solución: Agrega validación del lado del servidor a cada endpoint usando una librería de validación de esquemas. Zod es el estándar para proyectos TypeScript:

TypeScript
import { z } from 'zod';

const taskSchema = z.object({
  title: z.string().min(1).max(200),
  description: z.string().max(2000).optional(),
  priority: z.enum(['low', 'medium', 'high']),
});

// In your API route:
const parsed = taskSchema.safeParse(req.body);
if (!parsed.success) {
  return Response.json({ error: parsed.error }, { status: 400 });
}

Para cualquier campo que se renderice como HTML (comentarios, descripciones, biografías), también sanitiza la salida con DOMPurify antes de mostrarla.

Tiempo para reparar: 30–60 minutos.

Error 4: Sin Rate Limiting en Endpoints API

Cómo sucede: IA nunca agrega rate limiting a menos que lo pidas. Cada ruta API que expone tu aplicación puede ser golpeada miles de veces por segundo por cualquiera con un script.

Por qué es peligroso: Sin rate limiting, alguien puede hacer fuerza bruta en tu endpoint de login, raspar tu base de datos golpeando repetidamente endpoints de lista, sobrecargar tu servidor (denegación de servicio), o quemar tu cuota de API si tus endpoints llaman a servicios externos como OpenAI o Stripe.

Cómo identificarlo: Si ninguna de tus rutas API verifica cuántas solicitudes ha realizado recientemente una sola IP o usuario, no tienes rate limiting.

La solución: El enfoque más simple para aplicaciones alojadas en Vercel es un rate limiter en memoria para desarrollo y uno basado en Redis para producción. El Edge Middleware de Vercel puede manejar rate limiting básico. Upstash Redis (tier gratuito) con @upstash/ratelimit te da rate limiting de nivel producción en una pequeña cantidad de código.

Un buen punto de partida: 60 solicitudes por minuto para usuarios autenticados, 20 por minuto para usuarios no autenticados, y 5 por minuto para endpoints de login/signup (para prevenir fuerza bruta).

Tiempo para reparar: 20–45 minutos.

Error 5: Verificaciones de Autenticación Faltantes en Páginas y APIs Protegidas

Cómo sucede: IA genera una página de panel hermosa y rutas API que devuelven datos de usuario, pero no agrega middleware para verificar que el usuario esté realmente conectado. La página "funciona" porque durante el desarrollo siempre estás conectado. En producción, alguien puede acceder a la URL del panel directamente sin conectarse, u golpear el endpoint API y obtener datos de vuelta.

Por qué es peligroso: El acceso no autenticado a páginas protegidas significa que cualquiera puede ver paneles de usuario, paneles de administración o datos privados simplemente adivinando la URL. Las rutas API desprotegidas significan que cualquier herramienta como Postman o curl puede extraer datos sin credenciales.

Cómo identificarlo: Abre una ventana del navegador en incógnito (no conectado) y navega directamente a tu panel, configuración, o URLs de administración. Si puedes ver cualquier contenido sin ser redirigido a una página de login, tienes este problema. Luego intenta golpear tus rutas API directamente — si devuelven datos sin una cookie de sesión válida o token de autenticación, también están desprotegidas.

La solución: Agrega middleware de autenticación que se ejecute antes de cada ruta protegida. En Next.js App Router, crea un middleware.ts en la raíz de tu proyecto:

TypeScript
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const session = request.cookies.get('session');
  if (!session) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}

export const config = {
  matcher: ['/dashboard/:path*', '/settings/:path*', '/api/protected/:path*'],
};

Adapta el matcher para cubrir cada ruta que deba requerir autenticación. Prueba en incógnito después de implementar.

Tiempo para reparar: 15–30 minutos.

Cómo Prevenir Estos en Proyectos Futuros

El patrón es claro: IA genera código que funciona pero omite la seguridad porque no lo pediste. La solución es pedirlo de antemano.

Agrega esto al final de tu prompt inicial para cualquier proyecto vibe-coded:

Fragmento de prompt
SECURITY REQUIREMENTS:
- All secrets in environment variables (never hardcoded)
- Supabase RLS enabled on all tables with per-user policies
- Server-side input validation on every API route (use Zod)
- Rate limiting on all public endpoints
- Authentication middleware on all protected routes
- No service role key in client-side code

Esto no lo atrapará todo, pero elimina las cinco vulnerabilidades más comunes en el primer intento en lugar de requerir una limpieza más tarde.

Si quieres mejorar en la escritura de prompts que produzcan código más seguro desde el principio, nuestro optimizador de prompts gratuito puede ayudarte a estructurar tus instrucciones. Y para un recorrido completo de seguridad, consulta nuestra guía paso a paso: Cómo Asegurar una Aplicación Vibe-Coded Antes de Entregarla a Clientes.

Esto es lo que hacemos cada semana. Un análisis profundo sobre herramientas de IA, flujos de trabajo y opiniones honestas — sin hype, sin relleno. Únete a nosotros →

Divulgación: Algunos enlaces en este artículo son enlaces de afiliados. Solo recomendamos herramientas que hemos probado personalmente y usamos regularmente. Consulta nuestra política completa de divulgación.