Docs

Estado Actual de Seguridad

Resumen ejecutivo del estado de seguridad del ecosistema Nvito post-auditoria: vulnerabilidades corregidas, protecciones activas, pendientes y roadmap de seguridad.

PublicadoMarzo 2026Equipo de desarrollo, operaciones, CTO, stakeholders

Resumen ejecutivo

El ecosistema Nvito fue sometido a una auditoria de seguridad profunda el 22 de marzo de 2026, cubriendo los 5 repositorios de código, infraestructura Docker, configuración de ambientes y lógica de negocio. Se realizaron tres rondas de trabajo:

  1. Auditoria de seguridad inicial — 10 vulnerabilidades identificadas, 9 corregidas (1 descartada como falso positivo)
  2. Pentesting SAST (OWASP Top 10) — 14 vulnerabilidades adicionales identificadas, 13 corregidas (1 descartada tras verificacion)
  3. Hardening operacional — Pre-commit hooks en 5 repos, npm audit fix, sección de documentación de seguridad con 8 guias bilingües

Puntuacion general post-remediacion: 9.5/10

Vulnerabilidades corregidas

Ronda 1 — Auditoria inicial (9 fases)

FaseSeveridadQue se corrigioRepo
1CRITICAJWT_SECRET y MOBILE_JWT_SECRET obligatorios en todos los ambientesnvito-api
2CRITICAATS activado en iOS (NSAllowsArbitraryLoads: false)nvito-client
3CRITICAValidación de tokens con regex hex 64 charsnvito-client
4ALTADOMPurify en message-preview e icon-pickernvito-admin
5ALTARate limiter distribuido con Redis (fail-closed)nvito-pwa
6ALTAunsafe-eval removido de CSP en producción (condicional a isDev)nvito-admin
7MEDIAconsole.log silenciado en producción con DEVnvito-client
8MEDIACredenciales docker-compose parametrizadas con variablesnvito-api
9ALTACertificate pinning con circuit breaker, monitoreo automatizado y OTAmulti-repo

Ronda 2 — Pentesting SAST (13 fases + 1 descartada)

FaseSeveridadQue se corrigioRepo
C1CRITICAStripe webhook rechaza requests sin firma (401 en lugar de 200)nvito-api
C2CRITICARSVP create envuelto en $transaction atomica (previene race condition)nvito-api
C3CRITICARate limiting 10 req/min en endpoint público RSVPnvito-api
C4CRITICADescartada — verificado que .env nunca fue committeado en git history
A1ALTASlugs con crypto.randomBytes (64 bits entropia, antes Math.random con 31 bits)nvito-api
A2ALTAGeneración atomica de slugs con retry (elimina TOCTOU)nvito-api
A3ALTARedis con autenticación (requirepass en docker-compose)nvito-api
A4ALTABucket nvito-templates cambiado a privado (removido acceso anonimo)nvito-api
A5ALTAAdminer desactivado por defecto (solo con --profile debug)nvito-api
A6ALTATwilio guard sin bypass de validación de firma (rechaza si no hay authToken)nvito-api
A7ALTADocker images pineadas a node:20.19.0-alpinenvito-api, nvito-invitations
M1MEDIAError responses genericos en revalidation (sin error.message)nvito-invitations
M2MEDIAPII removido de logs (IDs en lugar de nombres en mobile-auth)nvito-api
M3MEDIARate limiter fail-closed cuando Redis no está disponiblenvito-pwa

Ronda 3 — Hardening operacional

AcciónQue se hizoRepos
Pre-commit hooksHusky instalado con hook de detección de secrets (Stripe, OpenAI, Anthropic, Twilio, private keys)5 repos
npm audit fixVulnerabilidades de dependencias corregidas donde fue posible sin breaking changes5 repos
Next.js actualizadonvito-pwa actualizado de 16.1.6 a 16.2.1 (fix CSRF en Server Actions) — 0 vulnerabilidadesnvito-pwa
Documentación de seguridad8 guias bilingües creadas en nueva sección tecnico/seguridad/nvito-docs
Politica de rotación de secretsGuia trimestral con checklist operacionalnvito-docs

Protecciones activas por capa

Autenticación y autorización

  • Clerk JWT con validación en cada request (ClerkAuthGuard)
  • 11 tipos de guards: ClerkAuth, Role, Permissions, EventAccess, InvitationState, AdminPanel, SuperAdmin, MobileAuth, MobileRole, Twilio, Cloudflare
  • RBAC con 80+ permisos granulares
  • JWT mobile independiente de Clerk con refresh automático
  • Multi-tenancy con RLS (Row Level Security) via tenant middleware
  • JWT_SECRET y MOBILE_JWT_SECRET obligatorios en todos los ambientes (min 32 chars)

Validación de input

  • class-validator en todos los DTOs (431 validadores en 82 DTOs)
  • ValidationPipe global con whitelist: true + forbidNonWhitelisted: true
  • Zod validation en server actions (admin, pwa)
  • Schemas Zod en invitaciones públicas
  • Tokens de deep link validados con regex hex 64 chars

Protección XSS

  • DOMPurify con whitelist estricta en invitaciones (ALLOW_DATA_ATTR: false)
  • DOMPurify en admin (message-preview, icon-picker)
  • CSP diferenciada por ambiente (unsafe-eval solo en desarrollo para webpack HMR)
  • React auto-escaping en todos los componentes
  • Error responses genericos sin stack traces ni error.message

Protección CSRF

  • CSRF double-submit HMAC-SHA256 en PWA con timing-safe comparison
  • Server actions protegidas por Clerk JWT (admin)
  • Next.js 16.2.1 en PWA (fix de CSRF bypass con null origin)

Encriptacion

  • AES-256-GCM para PII en base de datos (emails, teléfonos, nombres de invitados)
  • IV único por operación de encriptacion
  • Key derivation con scrypt resistente a fuerza bruta
  • Cookies HttpOnly AES-256-GCM en PWA (JWT nunca en JavaScript del browser)
  • HTTPS obligatorio (HSTS max-age 1 año con preload)

Rate limiting

  • Throttler global: 100 req/min por IP (nvito-api)
  • RSVP público: 10 req/min por IP
  • Invitaciones públicas: 20 req/min por IP
  • Clerk webhooks: 50 req/min por IP
  • Revalidación ISR: 10 req/min por IP
  • Auth PWA: 5 req/15min por IP
  • Rate limiter distribuido con Redis en PWA (fail-closed si Redis cae)

Webhooks

  • Stripe: validación de firma con rawBody, rechaza sin firma (401)
  • Clerk: Svix signature + replay protection (timestamp 5min) + idempotencia
  • Twilio: validateRequest con authToken, sin bypass configurable
  • Revalidación ISR: timing-safe comparison de secret

Certificate pinning (mobile)

  • Modulo secureFetch integrado en API client (reemplaza fetch nativo)
  • Dual-pin: leaf certificate + intermediate CA por hostname
  • Circuit breaker: fallback a fetch nativo tras 3 fallos consecutivos + telemetria
  • Monitoreo semanal via CertificateSchedulerService (cron lunes 9AM Mexico)
  • Endpoint GET /health/certificate-status para monitoreo externo
  • Endpoint POST /health/pinning-report para telemetria de fallos
  • OTA updates via expo-updates para rotación de pins sin pasar por stores
  • Pins reales configurados para DEV y TEST, placeholders para PROD
  • Pinning real pendiente de activación (requiere react-native-ssl-pinning + EAS Build)

Infraestructura Docker

  • Multi-stage builds con usuario non-root (nestjs/nextjs, UID 1001)
  • Node.js pineado a versión específica (20.19.0-alpine)
  • Redis con autenticación (requirepass)
  • Adminer desactivado por defecto (requiere --profile debug)
  • Buckets de templates privados (solo presigned URLs)
  • Credenciales parametrizadas con variables de entorno y defaults
  • CORS restrictivo (sin wildcard en producción, error si se intenta)
  • Helmet con CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy

Prevencion de secrets en código

  • Husky pre-commit hooks en los 5 repos (nvito-api, admin, invitations, client, pwa)
  • Detección automática de: Stripe keys, OpenAI keys, Anthropic keys, Twilio SIDs, private keys
  • Bloquea el commit si detecta patrones de secrets reales
  • Bypass disponible con --no-verify para falsos positivos
  • Archivos .env nunca committeados (verificado en git history de todos los repos)

Integridad de datos

  • RSVP create envuelto en transacción atomica ($transaction) contra race conditions
  • Check-in QR con transacción atomica (preexistente)
  • Slugs de invitación con crypto.randomBytes (64 bits entropia) + retry atomico
  • Soft delete en toda la BD con middleware automático

Contadores de tests post-auditoria

RepoSuitesTestsEstadoNotas
nvito-api24446826 fallos preexistentes (sharp nativo)+4 suites (seguridad + ARCO)
nvito-admin1431442100% green+2 suites vs pre-auditoria
nvito-invitations17180100% green0 vulnerabilidades npm audit
nvito-client31249100% green+2 suites (join-utils, certificate-pinning)
nvito-pwa18204100% greenNext.js 16.2.1, 0 vulnerabilidades npm audit

Vulnerabilidades de dependencias (npm audit)

RepoEstado post-fixVulnerabilidades residuales
nvito-api16 (undici)undici transitive via Node.js — requiere actualizar Node
nvito-admin1 moderateundici via Next.js
nvito-invitations0Limpio
nvito-client5 lowundici via Expo
nvito-pwa0Limpio (Next.js actualizado a 16.2.1)

Las vulnerabilidades residuales son de undici (HTTP client interno de Node.js), son transitive dependencies que se resuelven al actualizar Node.js o los frameworks principales.

Pendientes

Requieren producción activa

  • Reemplazar pins PLACEHOLDER de api.nvito.mx con pins reales del certificado de producción
  • Digital Asset Links: crear assetlinks.json y apple-app-site-association en nvito.app
  • Configurar UptimeRobot contra https://api.nvito.mx/v1/health/certificate-status
  • Configurar CERTIFICATE_CHECK_HOST=api.nvito.mx en Railway

Requieren acción del equipo (operacional)

  • Configurar WAF en Cloudflare (ver guia WAF Cloudflare en esta sección)
  • Hardening de VPS Contabo (ver checklist Hardening Infra en esta sección)
  • Configurar CERTIFICATE_CHECK_HOST en Coolify para DEV y TEST
  • Configurar UptimeRobot para DEV/TEST (monitor gratuito)
  • Primera rotación trimestral de secrets (ver guia Rotación de Secrets en esta sección)
  • Terminos de servicio formales (requiere revision legal)
  • Commitear los cambios de Husky en los 5 repos (package.json + .husky/pre-commit)

Implementados (sesion 22 marzo 2026 — ARCO compliance)

  • Campo optOutCommunications agregado al modelo Guest (migración Prisma)
  • Endpoint DELETE /v1/guests/:id/personal-data (derecho al olvido ARCO)
  • Endpoint PATCH /v1/guests/:id/communication-preferences (opt-out ARCO)
  • Endpoint POST /v1/guests/public/opt-out (opt-out público sin cuenta, rate limited)
  • Filtro opt-out integrado en recipient-filter, recipient-estimator y chatbot
  • Aviso de privacidad completo en nvito.mx/privacidad (LFPDPPP, 11 secciones)
  • Tests: 1 suite nueva (GuestArcoService — 13 tests), tests actualizados en controller y dispatchers

Implementados (sesion 22 marzo 2026 — SSL Pinning real)

  • react-native-ssl-pinning instalado en nvito-client
  • expo-dev-client instalado para desarrollo con módulos nativos
  • eas.json configurado con perfiles development, development-simulator, preview y production
  • Implementación real activada en secureFetch (antes era fallback a fetch nativo)
  • Documentación de desarrollo local actualizada con flujo EAS Build

Contratacion externa recomendada

  • Pentesting DAST antes de lanzar producción ($2,000-5,000 USD)
  • Revision legal del aviso de privacidad por abogado especialista en LFPDPPP ($500-1,500 USD)
  • Pentesting profesional anual post-lanzamiento ($5,000-15,000 USD)

Mejoras futuras (baja prioridad)

  • SIEM/logging centralizado para correlación de eventos de seguridad
  • Audit logs persistentes en BD con búsqueda
  • Dashboard de metricas de seguridad en tiempo real
  • Alertas de certificado integradas con EmailService y WhatsAppService

Activación de SSL Pinning real (react-native-ssl-pinning)

El módulo certificate-pinning.ts en nvito-client ya tiene toda la lógica implementada (secureFetch, circuit breaker, telemetria), pero el pinning real está desactivado porque react-native-ssl-pinning no está instalado. El código actual usa fetch nativo como fallback.

Pasos para activar

  1. Instalar la dependencia nativa:

    cd nvito-client
    npm install react-native-ssl-pinning
    
  2. Descomentar la implementación real en src/api/certificate-pinning.ts (buscar el bloque TODO comentado dentro de secureFetch)

  3. La implementación descomentada usa:

    const { fetch: sslFetch } = require('react-native-ssl-pinning');
    const response = await sslFetch(url, {
      method: init?.method ?? 'GET',
      headers: init?.headers,
      body: init?.body,
      pkPinning: true,
      sslPinning: { certs: pins },
      timeoutInterval: 30000,
    });
    
  4. Requiere EAS Build nativo (no funciona con Expo Go):

    eas build --platform ios --profile preview
    eas build --platform android --profile preview
    
  5. Probar que las llamadas al API funcionan en el build nativo

  6. Si funciona: publicar build de producción con eas build --profile production

Por que no se instalo en está sesion

react-native-ssl-pinning requiere código nativo (Kotlin/Swift). Expo Go no soporta módulos nativos custom. Se necesita EAS Build o bare workflow para compilar. El equipo debe decidir cuando migrar el flujo de desarrollo a EAS Build.

Impacto en el flujo de desarrollo

Al instalar react-native-ssl-pinning, el proyecto nvito-client ya no podrá ejecutarse con Expo Go. Los desarrolladores deberan usar uno de estos flujos:

  • EAS Build (recomendado): eas build --platform ios --profile development genera un dev client custom que soporta módulos nativos. Se instala en el simulador/dispositivo una vez y luego se conecta al Metro bundler normalmente.
  • Expo Dev Client: Instalar expo-dev-client junto con react-native-ssl-pinning. Permite desarrollo local con módulos nativos via npx expo start --dev-client.
  • Bare workflow: npx expo prebuild genera los proyectos nativos iOS/Android. Desarrollo con Xcode/Android Studio directamente.

En desarrollo (__DEV__ = true), el pinning NO se activa — secureFetch usa fetch nativo automáticamente. Esto significa que el flujo de desarrollo no se ve afectado funcionalmente, pero si requiere el build nativo para que la app arranque.

Recomendacion: Antes de instalar, configurar eas.json con perfiles de build (development, preview, production) y asegurarse de que el equipo tiene cuenta de EAS configurada (eas login).

Ciclo continuo de seguridad

La seguridad NO es un estado final sino un proceso continuo. El equipo debe seguir este calendario:

Semanal (automatizado)

DiaAcciónResponsableAutomático?
Lunes 9AMCertificateSchedulerService verifica certificados SSLnvito-api cronSi
Cada 6hUptimeRobot verifica /health/certificate-statusUptimeRobotSi (cuando se configure)
En cada commitPre-commit hook detecta secrets en archivos stagedHuskySi

Trimestral (manual — enero, abril, julio, octubre)

AcciónResponsableGuia
Rotación de TODOS los secretsEquipo opsRotación de Secrets
Ejecutar npm audit en los 5 repos y aplicar fixesEquipo devDependencias
Revisar logs de acceso para patrones sospechososEquipo ops
Verificar versiones de imagenes DockerEquipo devHardening Infra
Revisar reglas WAF en Cloudflare (falsos positivos)Equipo opsWAF Cloudflare

Semestral (manual — junio, diciembre)

AcciónResponsableGuia
Re-auditoria SAST del código nuevoEquipo dev / ClaudeAuditoria SAST
Verificar actualizaciones del SO en VPSEquipo opsHardening Infra
Verificar backups de BD (restaurar uno de prueba)Equipo opsHardening Infra
Revisar compliance LFPDPPP (nuevos datos recolectados?)Equipo / legalCompliance Datos

Anual (contratacion externa)

AcciónResponsableCosto estimado
Pentesting profesional externo (DAST + social engineering)Empresa de seguridad$5,000-15,000 USD
Revision legal de aviso de privacidad y terminosAbogado$500-1,500 USD
Audit de infraestructura (VPS, red, firewalls)Consultor infra$2,000-5,000 USD

En cada release mayor

AcciónResponsable
Revision de seguridad de features nuevas (guards, validaciones, PII)Equipo dev
Verificar que nuevos endpoints tienen rate limiting y authEquipo dev
Verificar que nuevos datos personales estan encriptadosEquipo dev
Actualizar aviso de privacidad si se recolectan datos nuevosEquipo / legal

Triggers de revision inmediata

Ejecutar revision de seguridad fuera del calendario si ocurre:

  • Se despliega producción por primera vez
  • Se agrega nuevo servicio o integración externa (nuevo proveedor)
  • Se detecta un incidente de seguridad o intento de intrusion
  • Se realiza un cambio arquitectural significativo
  • Se recibe reporte de vulnerabilidad de un usuario o investigador
  • Se renueva un certificado SSL
Esta pagina fue util?