← Tilbage til My Medicus
Sprog · Language
🇩🇰 DK🇬🇧 EN🇪🇸 ES🇩🇪 DE🇫🇷 FR🇮🇹 IT🇵🇹 PT🇹🇷 TR

¿Cuál es vuestra seguridad respecto a My Medicus?

medicus.global · 2026-05-05


La voz del paciente

"Toda la información la he introducido yo mismo, y consiento que
el personal de emergencias y los médicos puedan leerla — para darles
el mejor conocimiento previo posible de mi situación personal,
especialmente en una emergencia. Mi amor por la vida es mayor que
las normas del país sobre protección de datos."

Esa es la decisión adulta y voluntaria detrás de cada perfil My Medicus creado. Nuestra tarea es honrar la elección del paciente: guardar los datos de forma segura, mostrarlos solo a quien tiene el PIN correcto, dejar que el paciente vea cada escaneo, y permitir que el paciente revoque la tarjeta en el segundo en que se pierde. El resto de este documento explica cómo.


Pregunta

"¿Cuál es vuestra seguridad respecto a My Medicus?"

Respuesta — nuestro punto de vista

En una emergencia, el mayor deseo del paciente es recuperarse. Eso es a quien servimos. La seguridad es el medio, no el fin.

Tres principios están por encima de todo:

  1. El paciente es el remitente. Toda la información en la tarjeta es introducida por el paciente con su consentimiento. No importamos desde otras bases de datos. Menos es más.
  2. La comparación es el día a día, no un estado ideal. Una cartera perdida contiene número de identidad, tarjeta sanitaria, tarjeta de donante, tarjetas de crédito, fotos. La farmacia grita el número de identidad por encima del mostrador. Nuestra tarjeta es mejor que la exposición que ya ocurre cada semana — cifrada, bloqueada por PIN, con registro de auditoría, revocable.
  3. Hacemos todo lo posible y somos honestos sobre lo que no podemos. Cuando un paramédico escanea legítimamente la tarjeta, puede hacer una foto. No podemos impedirlo. Defensa: el paciente ve cada escaneo en su "Mi registro" y puede revocar la tarjeta con un clic.

Qué se ha probado concretamente

Hemos documentado 19 escenarios de ataque contra My Medicus y hemos ejecutado cada uno contra el sistema en producción. El resultado se describe abajo — sin lenguaje de marketing, sin "estándar de la industria", sin "mejores prácticas". Solo lo que se ha probado concretamente.


Qué se probó

19 escenarios de ataque contra dos cuentas en la base de datos en vivo — una cuenta demo y un usuario real nuevo. Herramientas: peticiones HTTP directas, ejecución paralela, introspección SQL de la base de datos de producción, parsing de respuestas.

Resultado: 14 ataques se encontraron con defensas que aguantaron. 5 vulnerabilidades fueron encontradas y cerradas el mismo día.

Las 14 capas de defensa que aguantaron

Ataque Por qué falló el ataque
Robo de toda la base de datos Alergias, medicación, números de identidad, pasaporte, EHIC y números de seguro están cifrados con AES-256-GCM. La clave vive en un almacén de secretos separado, nunca en la base de datos. Si robas el archivo DB, obtienes texto ilegible
Fuerza bruta sobre PIN de 6 dígitos Retrasos progresivos se activan al 5º intento incorrecto: 5 seg → 30 seg → 60 seg entre cada uno
Inyección SQL en formulario de login Todas las consultas a la base de datos usan consultas parametrizadas — cinco payloads de inyección distintos fueron rechazados
Llamadas API directas sin login Todos los endpoints protegidos devuelven HTTP 401
Adivinanza de tokens Los tokens son 32 caracteres hex derivados vía SHA-256. Espacio de búsqueda: 16^32. 50 intentos aleatorios → 0 aciertos
Path-traversal a backups o config /_db_backups/, /.env, /.git, /medicus.db, /wp-config.php devuelven todos 404
Enumeración de emails vía "olvidé contraseña" Respuesta genérica consistente independientemente de si el email existe — sin fuga de información
XSS en campos públicos El servidor rechaza entrada malformada, sin reflexión de HTML/JS
Robo físico de cartera sin el PIN de la tarjeta El bloqueo PIN detiene todos los intentos no correctos
10 intentos paralelos de fuerza bruta El rate-limit aplica por token, no por petición
Borrado del registro de auditoría vía endpoint DELETE No hay endpoints DELETE expuestos
Adivinanza de admin-token (admin, 1234, letmein) Todos devuelven 401
Intentar que el servidor filtre secretos vía payloads de error Ni clave de cifrado ni secretos de Stripe aparecen en la salida de error
Abuso cross-origin desde otro sitio El navegador bloquea por política same-origin

Las 5 vulnerabilidades encontradas y cerradas

# Qué Severidad Qué se hizo
F1 Login respondía 200 ms más lento cuando el email estaba registrado que cuando no. Un atacante podía determinar si una cuenta existe 🔴 Crítico Login ahora ejecuta verificación Argon2id siempre (también contra emails desconocidos, con un hash dummy). Tiempo de respuesta constante. Mensaje de error genérico
F2 Sin cabeceras de seguridad (HSTS, CSP, X-Frame, X-Content-Type, Referrer-Policy, Permissions-Policy) 🔴 Crítico Las 6 cabeceras se añaden ahora en todas las respuestas vía middleware. CSP bloquea script/img/style/frame a sources en lista blanca
F3 Una tarjeta robada tiene QR + PIN impresos directamente en ella. El ladrón obtiene acceso hasta que el dueño revoque 🟠 Alto (1) Paciente ve cada escaneo en su panel ("Mi registro" — prefijo IP, país, hora). (2) Dueño puede con un clic revocar la tarjeta → todas las tarjetas impresas mueren al instante + se genera nuevo PIN
F4 /admin devolvía SPA-HTML a todos, lo que revelaba la existencia del panel admin 🟡 Bajo Devuelve ahora el mismo 404 que rutas inexistentes para usuarios no autenticados
F5 Forgot-password podía abusarse para inundar la bandeja de un objetivo (1.000 mails/hora) — y a la vez dañar nuestra reputación de remitente 🟠 Alto Si el usuario tiene un token reset válido (máx 2 horas), se reutiliza en lugar de enviar nuevo mail. Plus rate-limit por email de 2/min

Lo que conscientemente NO hemos construido — y por qué

Elección Razón
Sin autenticación nacional en la vista paramédica El paciente está inconsciente en el campo de golf. El paramédico no tiene autenticación nacional, y aunque la tuviera, no tenemos 90 segundos para entrarles. PIN-en-tarjeta es la respuesta práctica
No "zero-knowledge" El servidor PUEDE descifrar los campos — es condición para que el paramédico pueda ver datos. No llamamos "zero-knowledge" a algo que no lo es
Sin importación automática de datos Cada campo es elegido por el usuario. Sin auto-importación desde otras plataformas de salud

Contra qué no podemos protegernos

Si un paramédico escanea legítimamente la tarjeta con el PIN correcto, puede fotografiar la pantalla. No podemos impedirlo — es el precio de que los datos puedan mostrarse en una emergencia. Defensa:

Es el mismo modelo de seguridad que una pulsera de identificación médica física para diabéticos: los datos son visibles para el personal de emergencias, aceptamos que un carterista también pueda verlos. La diferencia es que nuestro modelo da al paciente control sobre quién ve qué y cuándo — no solo visibilidad.

A qué nos comprometemos


¿Preguntas? Escribe a peter@medicus.global

medicus.global · security-my-medicus-es.md