Entre el 20 y el 27 de mayo de 2026, CULTIVA Seguridad realizó una prueba de penetración externa de la plataforma web NutriFlow (app.nutriflow.io y api.nutriflow.io), que gestiona historiales clínicos y datos nutricionales de más de 340 clínicas clientes.
El hallazgo más grave es una inyección SQL no autenticada en el motor de búsqueda de la API que permite extraer la tabla completa de usuarios —incluyendo contraseñas con hash, emails y datos de suscripción— con una sola petición HTTP. Combinada con un token JWT firmado con una clave que estuvo pública en npm, un atacante podría tomar el control de cualquier cuenta sin necesidad de credenciales.
La postura de seguridad actual es inaceptable para una plataforma que maneja datos sanitarios sujetos al RGPD. Tres vulnerabilidades críticas/altas permiten un escenario de compromiso completo de la base de datos y acceso transversal entre clientes (cross-tenant). La empresa debe ejecutar las remediaciones prioritarias antes de continuar procesando datos de pacientes.
Implementar SAST en CI/CD para Node.js — las vulnerabilidades de inyección SQL y XSS son detectables automáticamente antes de llegar a producción.
Cubre hallazgos #1, #2, #4Adoptar gestión centralizada de secretos (HashiCorp Vault o AWS Secrets Manager) y rotar inmediatamente todas las claves expuestas en repositorios públicos.
Cubre hallazgo #3Revisar el modelo de autorización multi-tenant: introducir validación de tenant_id en cada capa (API gateway, ORM, base de datos) con tests de regresión de aislamiento entre clientes.
| Campo | Detalle |
|---|---|
| Cliente | NutriFlow S.L. — Plataforma SaaS de gestión nutricional para clínicas |
| Tipo de prueba | Pentest externo + aplicación web (caja gris) |
| Alcance | app.nutriflow.io, api.nutriflow.io |
| Fuera de alcance | Infraestructura de terceros (Stripe, SendGrid), pruebas DoS, ingeniería social |
| Ventana de pruebas | 20–27 mayo 2026, horario 22:00–06:00 UTC |
| Metodología | PTES + OWASP Testing Guide v4.2 + CVSS v3.1 |
| Credenciales proporcionadas | 2 cuentas de usuario estándar en entorno staging (configurado como producción) |
| Equipo | Marta Reyes (lead), Carlos Vidal (web) |
El parámetro q del endpoint /api/v2/search se concatena directamente en la consulta SQL sin sanitización. Un atacante externo no autenticado puede extraer la totalidad de la base de datos, incluyendo ~34.000 registros de pacientes con datos de salud (RGPD categoría especial) y ~1.200 cuentas de profesionales con hashes de contraseña.
users (~1.200 registros de profesionales de salud)patients (~34.000 registros con datos de salud RGPD Art.9)', --, UNION en campos de búsqueda.UNION SELECT en logs de WAF/API.Se encontró la clave de firma de tokens JWT (JWT_SECRET=nutrifl0w_s3cr3t_2024) hardcodeada en el archivo config/defaults.js del paquete npm nutriflow-shared-utils@0.8.2, publicado en el registro público de npm. Con esta clave, cualquier persona puede forjar tokens JWT válidos para cualquier usuario de la plataforma.
JWT_SECRET a una clave aleatoria de 256 bits. Invalidar todos los tokens activos. Verificado en retest.git-secrets o Trufflehog en el pipeline de CI para detectar futuros leaks antes del push.El endpoint de consulta de pacientes acepta IDs numéricos secuenciales sin verificar que el paciente pertenezca al tenant del usuario autenticado. Un profesional de la Clínica A puede leer, modificar y eliminar historiales de cualquier paciente registrado en la plataforma —incluidos pacientes de competidores o clínicas no relacionadas.
WHERE patient_id=? AND tenant_id=? en todas las consultas de pacientes, extrayendo tenant_id del JWT verificado, no del request. Verificado en retest.Las notas clínicas se renderizan en el panel del médico con innerHTML sin escapar. El input se sanitiza ahora en el servidor (corrección parcial), pero no existe Content Security Policy. Un paciente podría inyectar JavaScript que exfiltre el token de sesión del profesional o realice acciones en su nombre.
Content-Security-Policy: default-src 'self'; script-src 'self' eliminando fuentes inline.textContent en lugar de innerHTML para notas de usuario.La cabecera Access-Control-Allow-Origin: * combinada con Access-Control-Allow-Credentials: true permite que cualquier página web maliciosa realice peticiones cross-origin autenticadas a la API usando la sesión activa del médico/administrador.
app.nutriflow.io) y eliminar el wildcard cuando credentials: true.Búsqueda en npm registry del paquete nutriflow-shared-utils. Extracción de JWT_SECRET del bundle publicado.
Finding #3 Alto · CVSS 8.1Con la clave extraída, se firma un JWT con role: superadmin. Acceso inmediato a todos los endpoints de administración.
Finding #3 Tiempo estimado: 2 minConfirmada independientemente del token: el endpoint /api/v2/search es vulnerable sin autenticación. UNION-based injection extrae todas las tablas.
Finding #2 Crítico · CVSS 9.8Dump de tablas patients, users, appointments y clinical_notes. Datos de salud de categoría especial RGPD Art.9 expuestos. Sanción potencial: hasta el 4% del volumen de negocio anual.
Impacto máximo Notificación AEPD obligatoria <72h| Finding | Severidad original | Estado | Verificación | Fecha |
|---|---|---|---|---|
| #1 — IDOR pacientes | Alto | ✓ Corregido | Validación tenant_id confirmada en respuesta 403 | 2026-06-11 |
| #2 — SQLi búsqueda | Crítico | ✓ Corregido | UNION payload retorna error tipado; prepared statements verificados | 2026-06-11 |
| #3 — JWT hardcoded | Alto | ✓ Corregido | Token forjado con clave antigua retorna 401; nueva clave no extraíble | 2026-06-11 |
| #4 — Stored XSS | Medio | ⚠ Parcial | Input sanitizado pero CSP no implementado. Payload <img onerror> sigue ejecutando en Safari | 2026-06-11 |
| #5 — CORS permisivo | Medio | ✗ No corregido | ACAO: * con credenciales sigue presente en todas las rutas | 2026-06-11 |
| #6 — TLS 1.0 | Bajo | ✓ Corregido | ssl-enum-ciphers confirma TLS 1.2 mínimo; TLS 1.0/1.1 deshabilitados | 2026-06-11 |
Próximo retest parcial: pendiente para findings #4 (XSS/CSP) y #5 (CORS) en cuanto el equipo de desarrollo confirme el despliegue. Contacto: seguridad@nutriflow.io
| Herramienta | Uso |
|---|---|
| Burp Suite Pro 2025.6 | Proxy, escáner activo, fuzzing de parámetros |
| sqlmap 1.8 | Verificación automatizada de inyección SQL |
| jwt_tool | Análisis y forja de tokens JWT |
| nmap 7.95 + ssl-enum-ciphers | Enumeración de servicios y evaluación TLS |
| nuclei 3.2 | Detección de vulnerabilidades conocidas |