Fix: v0 × seguridad
v0 hizo el frontend hermoso.
El backend te lo dejó a vos.
v0 es el mejor de los AI builders en lo que realmente hace: componentes React sobre shadcn/ui que se ven diseñados. El problema empieza cuando los componentes generados se vuelven, sin que nadie lo decida, la app entera. Auditorías independientes del output de v0 documentan API keys embebidas en componentes de cliente, secrets bajo NEXT_PUBLIC_ y route handlers sin autenticación (vibe-eval.com, ship-safe.co). Tus componentes valen la pena conservarlos — solo necesitan un backend que los trate como no confiables, como debería hacerlo todo backend.
Dónde se tuerce el código de v0: el patrón de demo se vuelve la app
v0 optimiza para un componente que anda en el preview, y la versión más corta de 'traer datos de una API' es un componente de cliente llamando a la API directo con la key inline. Las auditorías de apps generadas con v0 encuentran siempre el mismo set: llamadas a terceros hechas desde el cliente con credenciales embebidas, secrets guardados en env vars NEXT_PUBLIC_ — que Next.js por diseño compila al bundle público del navegador — XSS vía dangerouslySetInnerHTML, y handlers de formularios que validan en el navegador pero nunca en el server (vibe-eval.com). La auditoría de ship-safe.co lo dice sin rodeos: los route handlers generados por v0 hacen su trabajo pero rara vez incluyen checks de autenticación, así que cualquiera que adivine la URL es un usuario. Para ser justos con v0: no hay una brecha de titulares con su nombre como sí la hay con otros builders — pero el patrón es el mismo en todos los AI builders, y el patrón es lo que se explota.
Síntomas para grep-ear en un codebase de v0
Secrets bajo NEXT_PUBLIC_
Todo lo prefijado con NEXT_PUBLIC_ se compila al bundle del navegador — ese es su propósito documentado. El código generado estaciona seguido secrets reales ahí porque hace andar el componente de cliente. Grep-eá el prefijo y auditá cada hit.
Componentes de cliente llamando APIs de terceros
Un archivo 'use client' que fetchea OpenAI, Resend o Stripe directo le está shippeando su credencial a cada visitante. Esas llamadas van detrás de tu propia ruta de server.
Route handlers sin check de sesión
Los handlers generados en app/api típicamente parsean el request y hacen el trabajo — sin chequear quién pregunta. Cada handler necesita auth antes de la lógica, no como decoración en la página que linkea a él.
Server actions que le creen al formulario
Un server action que recibe form data es un endpoint público. Si no valida su input del lado del server, cualquiera puede invocarlo con cualquier payload — la validación del navegador nunca corrió para ellos.
dangerouslySetInnerHTML sobre contenido de usuarios
La API se llama así como advertencia. Si v0 lo usó para renderizar algo influido por usuarios, tenés una superficie XSS — estás a un script tag en un campo de perfil de que roben sesiones.
La pared: un solo contrato, enforzado de los dos lados
En useDeploy el cliente no puede inventar su propia idea del payload. Los schemas de Zod viven en un paquete de contratos compartido: el server valida cada request con ellos, y los tipos del cliente se generan del output OpenAPI del server. Cuando los dos driftean, CI rompe el build antes de que nada mergee — desaparece la clase exacta de agujero que deja pasar formularios validados solo en el navegador.
1 $ git push origin feat/profile-form
2 ci: typecheck ................ ✓
3 ci: api-types-fresh .......... ✗
4 apps/server/openapi.json is stale
5 client payload has field the server schema doesn't know
6 run `bun run generate:api` and commit the diff
7 ci: merge blocked
8
9 # la validación no es una cortesía client-side. es el mismo
10 # schema de Zod, enforzado donde el atacante no puede saltearlo.
Parado sobre la base, esto ya está hecho
Validación server-side en todos lados
Cada endpoint valida su input con schemas de Zod del paquete de contratos compartido. No hay ruta donde 'el formulario lo chequeó' sea el único check.
Auth chequeado donde importa
Las sesiones son filas server-side en Postgres, revocables, transportadas por cookies — y las rutas protegidas las verifican en middleware antes de que corra cualquier handler. Ningún handler shippea abierto por default.
RBAC y API keys por organización
Los permisos están scopeados por organización con control de acceso por rol, y el acceso programático va por API keys de verdad — no una URL adivinable como única barrera.
Los secrets se quedan en el server
Las credenciales viven en un schema de env validado por Zod cargado al boot, solo server-side. El foot-gun de NEXT_PUBLIC_ no tiene nada para cargar.
Firmado y throttleado en los bordes
Los webhooks salientes van firmados con HMAC; el tráfico entrante tiene rate limiting por tier, con los endpoints de auth bucketeados por IP y email.
450+ tests y un gate E2E
Los comportamientos de arriba no son aspiraciones — los asertan 450+ tests automatizados y una suite E2E de Playwright que gatea CI en cada merge.
Ruta de migración: tus componentes shadcn entran directo
Esta es la migración más fácil de todos los AI builders, porque el cliente de useDeploy es Next.js con shadcn/ui y Tailwind — el vocabulario exacto que genera v0. Tus componentes se pegan en el design system y agarran el theme de tokens. El trabajo real es recablear el flujo de datos: los fetches client-side a terceros se vuelven llamadas por el cliente tipado de openapi-fetch a tus propios endpoints, donde la key vive server-side y el payload se valida con Zod. Los server actions mapean a use cases detrás de controllers de Express — la misma ergonomía, pero con middleware de auth y validación de contrato adelante en vez de convención. Mové pantalla por pantalla: portá el componente, apuntalo a un endpoint tipado, borrá el fetch embebido. La mayoría de los equipos descubre que los componentes nunca fueron el problema — el piso que faltaba abajo, sí.
v0 × seguridad, sin vueltas
¿Puedo pegar componentes de v0 en la base tal cual?+
¿v0 en sí es inseguro?+
¿Qué pasa con mis server actions?+
¿Puedo seguir deployando el frontend en Vercel?+
Una licencia. Dos formas de tenerla.
CORE
Founder
Un snapshot congelado de UseDeploy. Tuyo para siempre, sin updates.
- Descarga del zip con versión frozen
- Código completo, uso comercial, proyectos ilimitados
- Los 800+ tests · todas las páginas de docs
- Refund a 14 días
LATEST + UPDATES
Lifetime
Siempre el último UseDeploy. Re-descargá cada release, gratis.
- Zip de la última versión — re-descargable para siempre
- Cada release futuro sin cargo extra
- Soporte Discord priority
- Los 800+ tests · todas las páginas de docs
- Refund a 14 días
Quedate con el frontend. Arreglá el piso.
Tus componentes de v0 están bien. Dales un backend con contratos validados, sesiones de verdad y permisos org-scoped — construido y testeado antes de que llegaras.