Cómo protegemos tus datos cuando el costo de equivocarse es tu familia.
MiLegado guarda lo que tu familia necesita si vos no estás. Por eso el modelo de seguridad es zero-knowledge: el servidor nunca ve tus datos en claro. Acá explicamos exactamente cómo, sin marketing.
Contenido
1. TL;DR
- El cifrado pasa en tu navegador con
WebCrypto APIantes de subir cualquier dato. - Tu password jamás llega al server en claro. Lo que enviamos al server es solo el hash (Argon2id) para autenticarte, y el contenido cifrado de tus items.
- Algoritmos:
AES-256-GCMpara items,scryptpara derivar la vault key,RSA-OAEP 2048para los sobres de custodios,SHA-256para hashes auxiliares. - Si MiLegado desaparece mañana, podés exportar un backup cifrado y descifrarlo offline con tu password — sin nuestro server.
2. Cifrado E2E — lo que el servidor NO ve
Cada item (clave bancaria, mensaje, documento) se cifra antes de salir de tu dispositivo. El servidor recibe solamente el blob cifrado + un IV. Lo que hay en nuestra base de datos para tu cuenta:
| Campo | ¿Qué guarda el server? | ¿Cifrado? |
|---|---|---|
| Tu email tal cual | No (lo necesitamos para login) | |
| Password | Hash Argon2id con sal | Hash one-way (no se puede revertir) |
| Título del item | Bytes cifrados con AES-GCM | Sí |
| Contenido del item | Bytes cifrados con AES-GCM | Sí |
| Archivos adjuntos | Bytes cifrados (R2 / Postgres bytea) | Sí |
| Vault key | Nunca tocada por el server | Derivada en tu browser desde tu password |
| Sobre RSA del custodio | Vault key cifrada con su pub key | Sí |
3. Cómo se derivan las claves
Vault key (la que cifra todos tus items)
Cuando te registrás, tu navegador genera un sal aleatorio de 16 bytes. Cada vez que ingresás tu password, derivamos la vault key haciendo:
vault_key = scrypt(password, salt, N=2^17, r=8, p=1, length=32)
Eso son ~256 MB de RAM y ~150ms en hardware típico. Diseñado para que un atacante con el blob cifrado tenga que hacer ese mismo cómputo por cada password que prueba — un ataque offline contra un password fuerte tarda años.
Cifrado del item
Cada item se cifra con AES-256-GCM usando la vault key y un IV de 96 bits aleatorio por item. GCM provee confidentialidad e integridad: si alguien modifica un byte del blob, la verificación de tag falla y el descifrado tira error en lugar de devolver basura.
Private key personal (para recibir sobres)
Generamos un keypair RSA-OAEP 2048 al signup. La private key se cifra inmediatamente con AES-GCM derivado de tu password (mismo flujo que el vault key, sal distinto) y se sube ya cifrada. La public key va plana — la usan otros users para mandarte sobres.
4. Acceso de custodios (sobres RSA-OAEP)
Cuando designás un custodio, se le manda un email con link de invitación. El custodio crea su cuenta y se genera su keypair RSA. Cuando volvés a entrar, tu navegador hace algo que el server no podría hacer:
- Toma tu vault key (derivada de tu password).
- La cifra con la public key del custodio (RSA-OAEP).
- Sube el resultado como "envelope" — el server lo guarda asociado a esa relación.
Si se gatilla el dead-man-switch (no hacés check-in por X días), el custodio puede pedir el envelope. Como solo su private key puede descifrarlo, recupera la vault key y a partir de ahí descifra tus items. El server no puede ayudar — no tiene ni tu vault key ni la private key del custodio.
5. Login y 2FA
- Login: tu password se hashea con Argon2id (OWASP-recommended, memory-hard) en el server. El hash se compara constant-time con el guardado.
- Rate limiting: 5 intentos por IP cada 15 min en login, 3/h en password reset, 5/15min en cambio de password.
- 2FA TOTP: opcional pero recomendado. Compatible con Authy, Google Authenticator, 1Password.
- Recovery codes: al activar 2FA generamos 10 códigos one-shot. Cada uno permite UN login si perdés el celular.
- Alerta de dispositivo nuevo: si entrás desde una IP+browser que no vimos en 90 días, te mandamos email tipo Stripe/GitHub con detalles + CTA "cambiar password si no fui yo".
- Logout-all-sessions: botón para invalidar todas tus sesiones activas en otros dispositivos.
- CAPTCHA: Cloudflare Turnstile en signup y password-reset frena bots automatizados.
6. Infraestructura y headers de seguridad
- HTTPS only:
Strict-Transport-Securityconmax-age=1y; includeSubDomains. - CSP estricto:
default-src 'self'; allowlist explícito para fonts/CDN/Turnstile. - X-Frame-Options: DENY: nadie puede embeber MiLegado en un iframe (anti-clickjacking).
- Cross-Origin-Opener-Policy + Cross-Origin-Resource-Policy: defense-in-depth contra ataques side-channel (Spectre, XS-Leaks).
- Cookie de sesión:
Secure+HttpOnly+SameSite=Lax. - Cloudflare WAF: bloqueo de tráfico de regiones no-cliente, Bot Fight Mode, AI Labyrinth contra crawlers.
- Email: SPF + DKIM + DMARC configurados para evitar spoofing de
noreply@milegadoapp.com. - Dependencias: Dependabot abre PRs automáticos cuando salen CVEs en flask/cryptography/etc.
7. Modelo de amenazas — qué SÍ y qué NO te protege
- Hackeo de nuestros servidores: solo ven blobs cifrados, no contenido.
- Empleado de MiLegado curioso: ningún empleado puede leer tu data.
- Subpoena: si nos piden tus items, podemos entregar los blobs cifrados pero no podemos descifrarlos.
- Pérdida de password con custodios: tus custodios pueden recuperar acceso (DMS o reset asistido).
- Robo de session cookie: 2FA + alertas + logout-all-sessions.
- Phishing de password: 2FA limita el blast radius.
- Pérdida total del password sin custodios designados: nadie puede recuperar tus datos. El password ES la llave.
- Malware en tu navegador o dispositivo: si te keyloggean el password, todo cae. Mantené tu OS al día y no instales extensiones random.
- Password débil: exigimos zxcvbn ≥ 3 (años de cómputo) pero no inventamos seguridad si vos elegís
password123. - Ataques cuánticos futuros: RSA-2048 va a caer eventualmente. Vamos a migrar antes de que sea exploitable.
8. Reportar una vulnerabilidad
Si encontrás algo, mandanos un mail a security@milegadoapp.com antes de publicarlo. Damos crédito en este mismo documento si querés. Sin programa de bounty oficial todavía, pero si el bug es serio te mandamos algo material — escribinos.
También respetamos la RFC 9116 security.txt.
Última actualización del documento: ahora
Si algo de esto cambia, lo actualizamos acá Y mandamos email a usuarios paid.