
Checklist de Seguridad SaaS Antes del Lanzamiento: 40 Verificaciones que Hacemos Primero (2026)
Un checklist de seguridad SaaS antes del lanzamiento vale más que una pila de sellos de cumplimiento que todavía no tienes. Esta es la verdad incómoda: la mayoría de los checklists de lanzamiento te dicen qué asegurar y nunca te muestran cómo. Este incluye el código. Trabajamos con Next.js y Supabase, hemos visto cómo un solo filtro tenant_id faltante deja que una cuenta de prueba lea los datos de otro cliente, y el informe Cost of a Data Breach 2024 de IBM situó el promedio global en $4.88 millones. No necesitas SOC 2 para salir a producción. Necesitas la base de nivel de aplicación que ves abajo, agrupada, lista para ejecutar y mapeada a OWASP y NIST.
Conclusiones Clave
- No necesitas SOC 2 ni un pentest para lanzar. Necesitas la base de nivel de aplicación de abajo.
- El bug de lanzamiento más peligroso es la filtración de datos entre tenants por un chequeo
tenant_idfaltante. - Nunca construyas tu propia autenticación. Usa Auth.js, Clerk o Supabase Auth.
- Audita los prefijos
NEXT_PUBLIC_antes de desplegar. Es la forma más rápida de filtrar un secreto.
Esta base se corresponde con OWASP ASVS 5.0 y el NIST Secure Software Development Framework (SSDF), las dos referencias en las que más confía Google para este tema y, curiosamente, las dos que ninguna de las guías mejor posicionadas se molesta en citar.
Tu Checklist de Seguridad Previo al Lanzamiento (Versión Rápida)
Estos son los requisitos mínimos de seguridad antes de lanzar, agrupados en seis categorías. Cuarenta elementos. Recórrelos de arriba a abajo, entrégale las secciones de código a tu desarrollador, y trata cualquier elemento marcado como P0 en la tabla de prioridad de abajo como un bloqueador de lanzamiento.
Secretos y Configuración
.envestá en.gitignoredesde el primer commit y nunca se ha subido al repositorio.- Cada prefijo
NEXT_PUBLIC_yVITE_está auditado; ningún secreto llega al navegador. - Los secretos del servidor viven en un gestor (variables de entorno de la plataforma, AWS Secrets Manager, Vault), no en el repositorio.
- Cualquier clave que haya pasado alguna vez por el historial de git se rota antes del lanzamiento.
- Ningún secreto aparece en logs, payloads de error o el bundle de cliente.
- Has hecho grep sobre el bundle compilado en busca de claves activas (
grep -r "sk_live" .next/).
Autenticación y Acceso
- La autenticación se construye sobre una librería (Auth.js, Clerk o Supabase Auth), no está hecha a mano.
- La MFA está disponible en las cuentas.
- Las cookies de sesión configuran
Secure,HttpOnlyySameSite. - Ningún JWT ni token de sesión se guarda en
localStorage. - El RBAC y los roles de mínimo privilegio se aplican en el servidor, no solo se ocultan en la interfaz.
- Las contraseñas se hashean con Argon2 o bcrypt (solo si gestionas tu propia autenticación).
- Los flujos de restablecimiento de contraseña y verificación de email se prueban contra abuso.
Datos y Multi-tenancy
- Cada consulta lleva un filtro
tenant_id. - El scoping por tenant se aplica en la capa del ORM o del repositorio, no se recuerda consulta a consulta.
- La seguridad a nivel de fila (RLS) está habilitada y se entienden sus modos de fallo.
- Cada endpoint con ID de objeto ejecuta una verificación de propiedad (esto elimina el IDOR).
tenant_idse incluye en las claves de caché y en las rutas de almacenamiento de objetos.- Los datos están cifrados en reposo y en tránsito.
- Las firmas de pagos y webhooks (Stripe, etc.) se verifican en el servidor.
Dependencias y Cadena de Suministro
npm auditopnpm auditestá limpio de hallazgos altos y críticos (o han sido triados explícitamente).- Dependabot o Renovate está habilitado.
- Snyk o Socket ejecutan un SCA más profundo además de comprobaciones de malware y licencias.
- El lockfile se sube al repositorio.
- Ningún paquete abandonado o sin mantenimiento está en la ruta crítica.
- Las imágenes de contenedor se escanean si usas Docker.
Red y Transporte
- HTTPS se aplica en todas partes, con HSTS preload.
- Se configura una Content-Security-Policy (primero en modo report-only y después forzada).
X-Content-Type-Options: nosniffyX-Frame-Options/frame-ancestorsestán configurados.Referrer-PolicyyPermissions-Policyestán configurados.- CORS usa una lista de permitidos, nunca
*con credenciales. - El rate limiting protege la autenticación y los endpoints costosos.
- Cada endpoint valida la entrada con un esquema (Zod o similar).
Monitorización y Respuesta
- Los logs de auditoría centralizados registran quién accedió a qué, y cuándo.
- El manejo de errores nunca filtra stack traces a los usuarios.
- Las alertas se disparan ante anomalías de autenticación (picos de inicios de sesión fallidos, viajes imposibles).
- Los backups automatizados se ejecutan, y has probado una restauración.
- Existe un contacto de respuesta a incidentes y un runbook de una página.
- La monitorización de uptime y errores (Sentry o equivalente) está activa.
- Sabes cuál es el disparador para traer un pentest.
Prioridad de Corrección
No todos los elementos bloquean el lanzamiento. Esta tabla de triaje ordena la base según el daño si se omite, para que un founder sepa qué es innegociable. P0 = corregir antes de lanzar, P1 = corregir en la primera semana, P2 = corregir dentro del trimestre.
| Verificación | Categoría | Si te lo saltas | Esfuerzo de corrección | ¿Bloquea el lanzamiento? |
|---|---|---|---|---|
| Aislamiento entre tenants en cada consulta | Datos y Multi-tenancy | Un cliente lee los datos de otro | Medio | P0: bloquea el lanzamiento |
| Secretos fuera del bundle de cliente | Secretos y Configuración | Claves de API públicas, toma de cuentas | Bajo | P0: bloquea el lanzamiento |
| Verificación de propiedad en endpoints con ID de objeto | Datos y Multi-tenancy | IDOR: incrementar un id filtra registros | Bajo | P0: bloquea el lanzamiento |
| Auth sobre una librería, no hecha a mano | Autenticación y Acceso | Bugs de auth en producción, sesiones rotas | Medio | P0: bloquea el lanzamiento |
| HTTPS y HSTS en todas partes | Red y Transporte | Robo de tokens en tránsito | Bajo | P0: bloquea el lanzamiento |
| npm audit limpio de altos/críticos | Dependencias | CVE conocido en una dependencia transitiva | Bajo | P1: primera semana |
| Rate limiting en endpoints de auth | Red y Transporte | Credential stuffing, fuerza bruta | Bajo | P1: primera semana |
| Cabeceras de seguridad (CSP, HSTS, nosniff) | Red y Transporte | XSS, clickjacking, ataques MIME | Bajo | P1: primera semana |
| Logs de auditoría centralizados | Monitorización | No puedes ver ni demostrar una brecha | Medio | P1: primera semana |
| Restauración de backup probada | Monitorización | Un backup que no restaura no sirve de nada | Medio | P1: primera semana |
| MFA disponible en las cuentas | Autenticación y Acceso | Toma de cuentas más fácil | Bajo | P2: este trimestre |
| CSP forzada por completo más allá de report-only | Red y Transporte | Superficie residual de XSS | Medio | P2: este trimestre |
Secretos y Configuración: ¿Se Están Filtrando Claves en tu Bundle de Cliente?
La higiene de secretos en el lanzamiento significa que ninguna credencial llega jamás al navegador. El prefijo NEXT_PUBLIC_ en Next.js (y VITE_ en Vite) envía un valor a cada visitante, así que un prefijo mal puesto filtra una clave. Mantén .env fuera de git, guarda los secretos del servidor en un gestor, y haz grep sobre el resultado de tu build antes de desplegar.
Esta es la trampa que más vemos: NEXT_PUBLIC_ no significa "información pública". Significa "estoy enviando esto literalmente al navegador de cada visitante". Prefija así una clave secreta de Stripe o una service-role key, y quedará expuesta en el bundle para cualquiera que abra las DevTools.
# .env.local (el error)
NEXT_PUBLIC_STRIPE_SECRET=sk_live_51H... # MAL: se envía a cada navegador
STRIPE_SECRET_KEY=sk_live_51H... # OK: solo en el servidor
# Pública (segura de exponer) vs solo servidor
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... # la anon key está pensada para ser pública
SUPABASE_SERVICE_ROLE_KEY=eyJ... # nunca le pongas NEXT_PUBLIC_ a esta
# Detecta una clave filtrada antes de desplegar
grep -r "sk_live" .next/ # cualquier resultado significa que hay un secreto en tu bundle de clienteEl resto de la base de secretos es aburrido y no negociable: .env en .gitignore desde el primer commit, secretos del servidor en un gestor en lugar del repositorio, y rotación de cualquier clave que haya pasado alguna vez por el historial de git (borrar un commit no deshace la filtración). Un token de despliegue filtrado es exactamente cómo empiezan brechas como el incidente de Vercel, así que trata cada token como si ya estuviera en la lista de vigilancia de alguien.
Autenticación y Acceso: ¿Deberías Construir tu Propia Auth o Usar una Librería?
¿Deberías construir tu propia autenticación o usar una librería? Casi siempre, usa una librería. Auth.js, Clerk y Supabase Auth han absorbido años de casos límite que de otro modo redescubrirías en producción: fijación de sesión, revocación de tokens, abuso del flujo de restablecimiento. Construir la tuya solo se justifica con un ingeniero de seguridad dedicado y una razón por la que ningún proveedor encaja, algo poco frecuente.
Construir tu propia autenticación es la forma más cara de ahorrarte $25 al mes. Así se comparan las opciones, sin adornos.
| Opción | Mejor cuando | MFA integrada | Sesión por defecto | Trampa |
|---|---|---|---|---|
| Auth.js (NextAuth) | Quieres algo gratis, autoalojado y con control total | Vía providers/add-ons | JWT o base de datos | Tú asumes cada caso límite de seguridad |
| Clerk | Quieres MFA, UI y organizaciones listas para usar | Sí | Gestionada | Los planes de pago escalan con usuarios activos |
| Supabase Auth | Ya usas Supabase y RLS de Postgres | Sí | JWT | La calidad de las políticas RLS depende de ti |
| Construir la tuya | Tienes un ingeniero de seguridad y ningún proveedor encaja | Tú la construyes | Tú la construyes | La mayoría de los bugs de auth empiezan justo aquí |
Dos trampas hunden a los equipos que eligen una librería pero se saltan la configuración. Primero, revocar un JWT es genuinamente difícil, así que un token robado sigue siendo válido hasta que expira; mantén los tiempos de vida cortos y prefiere sesiones del lado del servidor para cualquier cosa sensible. Segundo, los tokens en localStorage son robables por cualquier payload de XSS, así que guarda las sesiones en cookies httpOnly con Secure y SameSite. Aplica el RBAC en el servidor, no ocultando botones en la interfaz.
Si tu SaaS incluye una funcionalidad de IA o LLM, trata la entrada del modelo también como un límite de autenticación no confiable. Consulta nuestra guía sobre cómo prevenir la inyección de prompts, porque un asistente liberado de sus restricciones con acceso a herramientas es un problema de control de acceso disfrazado de ventana de chat.
Datos y Multi-tenancy: ¿Cómo Evitas que un Tenant Lea los Datos de Otro?
El aislamiento entre tenants significa que cada consulta, clave de caché y ruta de almacenamiento está delimitada al tenant actual. Un filtro tenant_id faltante permite que un cliente lea los datos de otro, el bug de lanzamiento más peligroso que existe. La seguridad a nivel de fila ayuda, pero es un cinturón de seguridad, no un campo de fuerza, así que añade también verificaciones de propiedad en cada endpoint con ID de objeto.
Esta es la sección que ningún competidor cubre con código real, y es la razón por la que las filtraciones entre tenants se cuelan en producción. La corrección empieza por no confiar nunca en un ID por sí solo. Delimita cada lectura al tenant de quien la solicita, y aplícalo en la capa de datos para que nadie tenga que recordarlo consulta a consulta.
// MAL: sin scope de tenant. Cualquier id válido devuelve la fila de cualquier tenant.
const order = await db.order.findFirst({ where: { id } });
// BIEN: delimitado al tenant de quien llama en cada lectura.
const order = await db.order.findFirst({
where: { id, tenantId: session.tenantId },
});El fallo relacionado es el IDOR (referencia directa insegura a objetos), que el OWASP API Security Top 10 clasifica bajo API1: Broken Object Level Authorization. Una cuenta de prueba incrementa un ID en la URL y lee un registro que nunca debería ver. La Web Security Academy de PortSwigger tiene un tutorial completo sobre cómo los atacantes encuentran esto. La corrección es una sola verificación de propiedad.
// GET /api/invoices/1234, una cuenta de prueba incrementa el id
// y lee la factura de otro tenant. Un BOLA clásico.
const invoice = await db.invoice.findUnique({ where: { id } });
// Corrección: verifica la propiedad antes de devolver nada.
if (invoice.tenantId !== session.tenantId) {
return res.status(403).json({ error: "Forbidden" });
}Este es el marco mental que te mantiene honesto: todo IDOR es un fallo de aislamiento entre tenants, pero no todo fallo de aislamiento entre tenants es un IDOR. La seguridad a nivel de fila de Postgres detecta muchos de ellos en la base de datos, pero tiene modos de fallo silenciosos que vale la pena conocer antes de confiar en ella.
-- Postgres RLS: un cinturón de seguridad, no un campo de fuerza.
alter table orders enable row level security;
create policy tenant_isolation on orders
using (tenant_id = current_setting('app.tenant_id')::uuid);
-- Trampa de fallo silencioso: si olvidas el SET app.tenant_id en una
-- conexión pooled, la política lee el tenant de la solicitud ANTERIOR.La contaminación del connection pool, las fugas de contexto async y el envenenamiento de caché compartida derrotan al RLS en silencio, por eso el OWASP Multi-Tenant Security Cheat Sheet recomienda prefijar también las claves de caché y las rutas de almacenamiento con el tenant. El capítulo de control de acceso de OWASP ASVS 5.0 y la documentación de RLS de Supabase son las dos referencias que vale la pena leer completas aquí.
Dependencias y Cadena de Suministro: ¿Qué se Esconde en tu node_modules?
Tu app es tan segura como su dependencia transitiva más débil. Ejecuta npm audit o pnpm audit en CI y haz que el build falle ante hallazgos altos o críticos antes de lanzar nada. Añade Dependabot o Renovate para actualizaciones automáticas, y Snyk o Socket para comprobaciones más profundas de malware y licencias.
La trampa es ejecutar la auditoría una vez a mano, ver todo en verde, y no volver a hacerlo nunca más. Conéctala a la CI para que un nuevo CVE en un paquete que no has tocado siga bloqueando el merge.
# .github/workflows/ci.yml: bloquea el merge ante hallazgos altos/críticos
- name: Audit dependencies
run: npm audit --audit-level=high # una salida distinta de cero hace fallar el jobLa documentación de npm audit cubre los niveles de severidad y el flag --production si quieres ignorar hallazgos solo de desarrollo. Aun así, el escaneo automatizado es lo mínimo indispensable; para un análisis estático más profundo que detecte code smells y rutas de inyección que un escáner de dependencias no ve, consulta nuestro análisis de SonarQube. Sube tu lockfile al repositorio, elimina paquetes que llevan años sin una nueva versión, y escanea tu imagen de contenedor si despliegas con Docker.
Red y Transporte: ¿Qué Cabeceras de Seguridad Necesita Realmente un SaaS?
¿Qué cabeceras de seguridad necesita un SaaS? HTTPS más HSTS y un pequeño conjunto de cabeceras cierran los huecos más fáciles de explotar. Añade una Content-Security-Policy, una lista de permitidos en CORS en lugar de un comodín, y límites de tasa en la autenticación y los endpoints costosos. Valida cada entrada con un esquema como Zod para que los payloads maliciosos nunca lleguen a tu lógica.
No necesitas todas las cabeceras jamás inventadas. Necesitas esta lista corta, y la referencia de cabeceras de seguridad de MDN explica cada una en profundidad.
| Cabecera | Valor recomendado | Qué detiene |
|---|---|---|
| Strict-Transport-Security | max-age=63072000; includeSubDomains; preload | Degradación de protocolo, ataques SSL-strip |
| Content-Security-Policy | default-src 'self'; empieza en report-only | XSS, scripts inyectados, exfiltración de datos |
| X-Content-Type-Options | nosniff | MIME-sniffing que convierte una subida de archivo en un script |
| X-Frame-Options / frame-ancestors | DENY (o frame-ancestors 'none') | Clickjacking mediante iframes ocultos |
| Referrer-Policy | strict-origin-when-cross-origin | Filtración de URLs completas (y los tokens dentro de ellas) |
| Permissions-Policy | camera=(), microphone=(), geolocation=() | Scripts maliciosos accediendo a APIs del dispositivo |
Configura las cabeceras una sola vez, en el edge, y añade un limitador de tasa para que un script no pueda hacer fuerza bruta contra tu ruta de login toda la noche.
// next.config.js: cabeceras de seguridad en cada respuesta
const securityHeaders = [
{ key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "X-Frame-Options", value: "DENY" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
];
// Rate limiting en rutas de auth (ejemplo con Upstash)
const { success } = await ratelimit.limit(ip);
if (!success) return new Response("Too many requests", { status: 429 });Arranca tu CSP en modo report-only para no romper tu propia app, observa los reportes de violaciones durante unos días, y luego actívala en modo forzado. Mantén CORS con una lista de permitidos nombrada, y nunca combines * con credenciales.
Monitorización y Respuesta: ¿Cómo Sabrás si Has Sufrido una Brecha?
No puedes responder a lo que no puedes ver. Antes de lanzar, conecta logs de auditoría centralizados, alertas sobre anomalías de autenticación como picos de inicios de sesión fallidos, backups automatizados con una restauración probada, y un runbook de incidentes de una página. Un backup sin probar es una esperanza, no un backup, y el momento de escribir el runbook es ahora, no en mitad de un incidente.
Los datos de IBM sitúan el tiempo medio para identificar y contener una brecha en 258 días, y no puedes reducir ese número si tus logs no registran quién tocó qué. Centralízalos, activa alertas sobre las anomalías que importan (picos de inicios de sesión fallidos, logins con viajes imposibles, volúmenes de exportación repentinos), y asegúrate de que tu manejador de errores devuelve un mensaje limpio en lugar de un stack trace que mapea tus entrañas internas.
La detección moderna de brechas se apoya más en la monitorización de anomalías que en reglas estáticas; hay más detalles sobre cómo funciona esto de verdad en nuestro artículo sobre cómo la IA previene las brechas de datos. Para el respaldo del marco de referencia, el NIST SSDF (SP 800-218) expone las prácticas de respuesta y monitorización en lenguaje sencillo. Prueba una restauración antes de lanzar, no después de que tu base de datos desaparezca.
Lo Que Realmente Encontramos al Revisar Nuestros Propios Lanzamientos
Cuando nuestro equipo hace una revisión de seguridad previa al lanzamiento sobre un build, nuestro o de un cliente, dos fallos aparecen más que ningún otro. Primero: un secreto colándose en el navegador a través de un prefijo NEXT_PUBLIC_, normalmente una clave de API de terceros que alguien prefijó para que funcionara una llamada del lado del cliente. Segundo: al menos un endpoint sin su scope de tenant_id o sin verificación de propiedad.
El fallo de scope de tenant es el que da más miedo porque la app parece estar bien. Cada página carga. El bug solo aparece cuando alguien cambia un ID en la URL. En una revisión, GET /api/orders/:id devolvía cualquier pedido a cualquier usuario con sesión iniciada; una cuenta de prueba leyó los pedidos de otro tenant simplemente incrementando el número. La corrección fue de dos líneas: comparar order.tenantId con session.tenantId antes de devolver nada.
No te vamos a inventar una tasa de detección falsa aquí. Lo honesto y repetible es esto: la filtración de NEXT_PUBLIC_ y el scope de tenant faltante son las dos cosas que encontramos en casi cada primera revisión, y ambas son baratas de corregir una vez que sabes que hay que buscarlas. Por eso exactamente el checklist las pone primero como P0.
Si prefieres que un equipo haga esta revisión por ti antes del día de lanzamiento, ese es justo el trabajo que hacemos. Solicita una revisión de seguridad previa al lanzamiento →
Sobre el Autor
Mert Batur es Cofundador de Techsy.io, donde el equipo construye agentes de IA, sistemas de automatización y pipelines de voz/SDR para clientes B2B. Escribe sobre el stack de herramientas de LLM que el equipo de Techsy realmente usa en producción. Conecta en LinkedIn.
Preguntas Frecuentes
¿Qué debe incluir un checklist de seguridad SaaS antes del lanzamiento?
Seis categorías: secretos y configuración (mantén las claves fuera del bundle de cliente), autenticación y acceso (usa una librería, añade MFA), datos y tenancy (scoping por tenant_id más verificaciones de propiedad), dependencias (npm audit en CI), red y transporte (HTTPS, HSTS, CSP, rate limits), y monitorización y respuesta (logs de auditoría, backups probados, un runbook).
¿Es mi SaaS lo bastante seguro para lanzarlo?
Estás listo cuando la base P0 está completa: secretos fuera del bundle de cliente, aislamiento entre tenants en cada consulta, auth sobre una librería, HTTPS con cabeceras de seguridad, y un escaneo de dependencias limpio. La perfección no es el listón. Una app lanzada y monitorizada con la base cubierta gana a una "perfecta" que nunca llega a lanzarse.
¿Necesito un pentest antes de lanzar un SaaS?
No para lanzar legalmente. Prioriza uno si manejas pagos o PII, apuntas a compradores empresariales, o un auditor o inversor lo pide. En la etapa de MVP, invierte ese esfuerzo primero en la base de nivel de aplicación y en el OWASP Top 10. Un pentest encuentra más cuando los huecos obvios de IDOR y cabeceras ya están cerrados.
¿Necesito SOC 2 para lanzar un SaaS?
No. Ningún cliente espera SOC 2 de una startup que lanzó la semana pasada. Es una llave para desbloquear ventas empresariales, no una puerta de lanzamiento, y toma meses. Lanza con la base de nivel de aplicación, y empieza el proceso de SOC 2 cuando un acuerdo empresarial real lo necesite, no antes.
¿Debería construir mi propia autenticación o usar una librería como Auth.js, Clerk o Supabase Auth?
Casi siempre, usa una librería. Auth.js, Clerk y Supabase Auth ya han resuelto los casos límite de sesión, tokens y flujos de restablecimiento que causan la mayoría de los bugs de auth caseros. Construir la tuya solo se justifica si tienes un ingeniero de seguridad y un requisito estricto que ningún proveedor cumple, algo genuinamente poco frecuente.
¿Cómo mantengo los secretos fuera de mi bundle de cliente?
Audita cada prefijo NEXT_PUBLIC_ y VITE_, porque cualquier cosa con ese prefijo llega al navegador. Mantén .env fuera de git desde el primer commit, guarda los secretos del servidor en un gestor, y haz grep sobre tu bundle compilado (grep -r "sk_live" .next/) antes de desplegar para detectar una clave filtrada.
¿Cómo aíslo los datos de tenants en un SaaS multi-tenant?
Pon un filtro tenant_id en cada consulta y aplícalo en la capa del ORM o del repositorio para que sea automático. Activa la seguridad a nivel de fila y aprende sus modos de fallo (contaminación del pool, fugas async). Añade una verificación de propiedad a cada endpoint con ID de objeto para cerrar el IDOR, y delimita las claves de caché y las rutas de almacenamiento por tenant.
¿Qué cabeceras de seguridad necesita un SaaS antes del lanzamiento?
Como mínimo: Strict-Transport-Security (HSTS), una Content-Security-Policy, X-Content-Type-Options: nosniff, X-Frame-Options o frame-ancestors, Referrer-Policy, y Permissions-Policy. Arranca tu CSP en modo report-only, revisa las violaciones, y luego actívala en modo forzado. La documentación de cabeceras de seguridad de MDN lista los valores recomendados para cada una, y la tabla de cabeceras de arriba resume qué detiene cada una.
¿Es suficiente un escaneo automatizado como npm audit o Snyk?
Necesario pero no suficiente. Herramientas como npm audit, Snyk y Socket detectan CVEs conocidos y paquetes maliciosos, pero no pueden encontrar fallos de lógica de negocio y control de acceso como el IDOR o un scope de tenant faltante. Eso necesita un humano, una cuenta de prueba y una verificación de propiedad explícita. Ejecuta ambos: el escáner y una revisión manual.
La Conclusión: Un Checklist de Seguridad SaaS que Puedes Aplicar de Verdad
No necesitas ser perfecto para lanzar. Necesitas la base. Cierra primero los elementos P0: secretos fuera del bundle, aislamiento entre tenants en cada consulta, una verificación de propiedad en cada endpoint de objeto, auth sobre una librería, y HTTPS con cabeceras. Si vas a corregir una sola cosa antes del lanzamiento del viernes, que sea el aislamiento entre tenants, porque ese es el bug que filtra los datos de un cliente sin ninguna advertencia.
Todo esto se puede ejecutar hoy mismo, y nada de ello requiere un presupuesto de cumplimiento. Repasa las 40 verificaciones, entrégale las secciones de código a tu desarrollador, y lanza. ¿Quieres un segundo par de ojos antes de salir a producción? Solicita una consultoría gratuita y repasamos la lista contigo.