Fix: Bolt × seguridad
Bolt puso tu app en una pestaña del navegador.
Asegurate de que tus keys no estén ahí adentro.
Una auditoría de securityscanner.dev encontró que el 15% de las apps de Bolt exponía API keys hardcodeadas en el código del frontend. Y las keys expuestas no se quedan quietas: los bots scrapean los bundles recién deployados en cuestión de horas, y una key de OpenAI filtrada se convierte en la factura de uso de otro. Nada de esto significa que tu idea de producto estuviera mal. Significa que shippeó el patrón de demo — y los demos guardan secrets en lugares donde producción no puede.
Por qué las apps de Bolt filtran: el camino más corto a un demo que anda
Bolt construye y corre tu app adentro de WebContainers — todo se ejecuta en el navegador, y justo por eso se siente instantáneo. Pero esa arquitectura empuja el código generado hacia el todo-client-side: cuando le pedís a Bolt que integre OpenAI o Stripe, la versión que anda más rápido pone la key directo en el código del frontend, y eso es lo que suele tocarte. vibeappscanner.com documenta las vulnerabilidades recurrentes en casi cada app de Bolt que audita: keys service_role de Supabase expuestas, políticas RLS faltantes, y auth atornillado que renderiza una pantalla de login sin que la API verifique jamás quién llama. El input de usuario sin escapar suma stored XSS a la lista. Cada una es invisible en el preview. Todas las encuentra trivialmente cualquiera que abra devtools en tu app deployada.
El checklist de seguridad de Bolt — corrélo antes de que lo corra otro
Buscá keys en tu bundle
Deployá, mirá el código fuente y buscá 'sk-', 'sk_live' y 'service_role'. Bolt hardcodea seguido keys de terceros en archivos del frontend porque así andaba el demo. Cada hit necesita rotación, no solo borrado.
La key service_role en código del cliente
La key service_role de Supabase saltea todas las políticas RLS. Si aparece en cualquier lugar al que llegue el navegador, tu base de datos no tiene ningún control de acceso — sin importar qué políticas escribiste.
Auth que solo existe en la UI
Una página de login no prueba nada. Llamá a tus endpoints de la API directo con curl, sin autenticar. Si vuelven datos, tu auth es decoración — Bolt suele gatear la interfaz sin gatear la API.
Input de usuario sin escapar
Los componentes que genera Bolt suelen renderizar contenido de usuarios sin sanitizar. Un stored XSS en un campo de comentarios y un atacante corre JavaScript en la sesión de todos tus demás usuarios.
Nada que frene a un atacante
Probá 30 logins seguidos con contraseña incorrecta contra tu propia app. Si nada te frena, el credential stuffing corre a velocidad máxima contra cada cuenta que tenés.
La pared: un server que se niega a arrancar sin sus secrets
En useDeploy los secrets no están desparramados por los archivos fuente — viven en variables de entorno, y un schema de Zod los valida todos al boot. Si falta uno, el proceso sale con un error con nombre en vez de renguear hasta producción. Y como los secrets solo existen server-side, el bundle del cliente físicamente no puede filtrar lo que nunca recibe.
1 $ bun run start
2 ✗ Invalid environment:
3 BETTER_AUTH_SECRET Required
4 DATABASE_URL Required
5 error: process exited with code 1
6
7 # los secrets se validan al boot, solo server-side.
8 # el bundle no puede filtrar lo que el cliente nunca recibe.
Lo que ya viene resuelto en la base
Secrets validados al boot
Un único schema de env validado por Zod es la única casa de cada credencial. Nada secreto se puede importar desde código del cliente, así que 'la key en el bundle' deja de ser una clase de bug posible.
Webhooks de billing que sobreviven replays
Los webhooks de pago son idempotentes por externalOrderId sobre un outbox durable — un provider reintentando el mismo evento dos veces no puede cobrarle ni acreditarle doble a nadie.
Webhooks salientes firmados
Los webhooks que manda tu app van firmados con HMAC, así los receptores pueden verificar que vinieron de vos — la disciplina que querés de los dos lados del caño de webhooks.
Rate limiting por tier
El tráfico de lectura, escritura y auth tiene cada uno su propio limiter, con auth bucketeado por IP y por email. El test de las 30 contraseñas incorrectas del checklist de arriba acá se topa con un 429.
Aislamiento que no es opcional
Repositorios org-scoped y un query guard de Prisma hacen que las lecturas cross-tenant devuelvan 404. No existe el equivalente de 'me olvidé de prender RLS' porque no hay switch para dejar apagado.
Una suite de tests mirando todo
450+ tests automatizados más un gate E2E de Playwright en CI ejercitan los flujos de auth, la idempotencia de webhooks y las fronteras de tenant en cada merge.
Ruta de migración: del WebContainer a un backend de verdad
Exportá tu proyecto desde Bolt — descargá el código o pusheálo a GitHub. La UI React viaja bien; lo que no viaja es la arquitectura de todo-en-el-navegador. La migración es sobre todo una mudanza: cada fetch que llama a una API de terceros con la key embebida se vuelve una llamada a tu propio endpoint tipado, y la key se muda al env del server donde el schema de Zod la valida al boot. La lógica de negocio que vivía en componentes se vuelve use cases detrás de controllers de Express, tipados de punta a punta vía el contrato OpenAPI generado. Rotá cada key que alguna vez apareció en código generado por Bolt — asumí que todas se filtraron — y hacé la mudanza de a una integración: OpenAI primero si ahí está tu riesgo de gasto, Stripe después, y el resto. Tus usuarios ven la misma app. Tus keys dejan de ser públicas.
Bolt × seguridad, sin vueltas
Mi key de OpenAI ya se filtró. ¿Qué hago primero?+
¿Puedo quedarme con Supabase mientras migro?+
¿La base maneja bien los webhooks de Stripe?+
¿Esto es un rewrite?+
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
Shippeá la app sin shippear tus keys
Quedate con la velocidad que te trajo hasta acá. Mudate a una base donde los secrets se validan al boot, los webhooks son idempotentes y 450+ tests cuidan el piso.