Política de seguridad
Herkos maneja claves privadas y mensajes cifrados, así que nos tomamos en serio los informes de seguridad y preferimos enterarnos pronto antes que tarde.
Cómo informar de una vulnerabilidad
No abras una incidencia pública para un problema de seguridad.
Comunícalo en privado por correo a security@herkos.email.
Conviene incluir: cuál es el problema, cómo reproducirlo, en qué plataforma y versión lo has probado, y qué podría conseguir un atacante. Una prueba de concepto ayuda mucho.
Nunca incluyas tu propia nsec, clave secreta o secreto de bunker en un informe.
Intentamos acusar recibo en unos pocos días. Como Herkos es un proyecto pequeño, te pedimos un plazo razonable para corregirlo antes de hacerlo público. Nos gusta acreditarte en el aviso, salvo que prefieras lo contrario.
Qué entra en el alcance
La propia aplicación Herkos: el manejo y almacenamiento de claves, el cifrado y
descifrado de mensajes (incluidas las comprobaciones de remitente NIP-59 y el
aislamiento de Bcc en local_packages/nostr_mail), el bloqueo de la app, la
comunicación con relays y bridges, el manejo de adjuntos, y el proceso de
compilación y publicación. En Herkos Drive, también su paquete de protocolo
(packages/herkos_drive_protocol) y la página que abre sus enlaces
(herkos.app/f/); ver su propia sección, más abajo.
Qué queda fuera
- El protocolo Nostr y sus NIP en sí — eso se reporta upstream.
- Relays, bridges y servidores Blossom operados por terceros. Herkos trae valores por defecto, pero no los gestiona; informa a sus operadores.
- El proyecto original Nostr Mail Client, salvo que el problema sea específico de los cambios hechos en Herkos.
- El endurecimiento que ya documentamos como limitación conocida (más abajo).
Limitaciones conocidas, dichas claramente
Son decisiones de diseño, no vulnerabilidades. Preferimos escribirlas que dejar que alguien las descubra por las malas:
- El correo a direcciones tradicionales no va cifrado de extremo a extremo. Entre usuarios de Nostr se usa gift wrap NIP-17 y sí lo está. Cuando escribes a una dirección de correo normal, un bridge convierte el mensaje y puede leerlo.
- El bloqueo de la app (PIN y biometría) es una barrera de conveniencia, no cifrado en reposo. Frena a quien coge un dispositivo desbloqueado; no protege frente a un atacante con acceso completo al dispositivo o a su almacenamiento.
- En Windows no se puede exigir solo biometría. Windows Hello no permite seleccionar el método, así que el PIN del sistema sigue siempre disponible como alternativa.
- Perder tu clave es perder la cuenta. No hay recuperación, por diseño.
- Los metadatos no están del todo ocultos. Los relays pueden observar patrones de conexión, y todos ven tu dirección IP, aunque no puedan leer el contenido. Lo que Herkos no revela (desde el 30-09-2026) es quién escribe a quién cuando un relay pide autenticación NIP-42:
- Consultar dónde entregar. Las listas de relays y de Blossom del
destinatario se piden por una conexión aparte que nunca te identifica,
primero a relays que no exigen autenticación (
purplepag.es,user.kindpag.es,nos.lol,offchain.pub). - Perfiles y programador. El nombre y la foto que se muestran de cualquier otra persona (kind 0), y la lista de relays del DVM programador cuando programas o cancelas un correo, se piden igual: primero de forma anónima y, si un relay insiste, con la clave temporal que se explica abajo, nunca con la tuya (desde el 01-10-2026; antes, un relay que pedía autenticación recibía tu clave y podía saber de quién mirabas el perfil). Solo tu propio perfil se sigue leyendo como tú.
- Entregar. Los gift wraps van a los relays de mensajes privados del destinatario, por esa misma conexión aparte. Si alguno exige autenticarse, Herkos responde con una clave creada para eso y guardada solo en memoria, nunca con la tuya; cada cuenta del dispositivo tiene la suya. El relay sí puede ver que el mismo dispositivo (misma IP, misma clave temporal) envió varios sobres durante una sesión.
- Correos grandes. La copia cifrada de un correo de más de 32 KB se sube a servidores Blossom, también a los del destinatario. Solo tus propios servidores (tu lista de Blossom) reciben la subida autorizada con tu clave. Cualquier otro la recibe de forma anónima y, si exige una autorización, firmada con la misma clave temporal de antes (desde el 01-10-2026; antes, todos recibían tu clave). Un servidor que solo acepta claves conocidas la rechaza, y la copia queda en los demás.
- Tus propios datos. Al sincronizar tu buzón, etiquetas, ajustes y borradores, Herkos se identifica, si el relay lo pide, como la cuenta a la que pertenecen esos datos, también durante un cambio de cuenta. En tus propios relays eso no les dice nada nuevo: las peticiones ya nombran tu clave. Tus listas de relays y de Blossom son públicas y se piden sin identificarte; también se pregunta sin identificarte a los relays que vengan en un enlace.
- El estado de lectura y las carpetas son metadatos públicos (por ahora). Marcar un correo como leído, destacado o archivado, o moverlo, publica un evento de etiqueta NIP-32 sin cifrar ligado a tu clave pública, incluidos los nombres de las carpetas personalizadas. Quien te envió un correo y conoce su id puede saber cuándo actuaste sobre él. Cifrar esas etiquetas está previsto; hasta entonces, trata los nombres de carpeta como públicos.
- Las notificaciones push y el envío programado usan servicios de terceros.
El servidor push, si eliges uno (ninguno por defecto desde el 11 de
noviembre de 2026;
api.nmail.liconrelay.nmail.lisi lo pides), conoce tu clave pública, un token push y cuándo recibes correo; el DVM programador conoce tu clave pública y los mensajes —ya cifrados— que debe publicar. Ambos son opcionales y están documentados enPRIVACY.md. El texto de una notificación push lo elige el servidor push, y Herkos solo se fía de él cuando UnifiedPush lo entrega cifrado (RFC 8291); un aviso sin cifrar solo sirve para despertar a la app, que va a buscar el correo por su cuenta. - La versión web guarda tu clave en el navegador, que es el peor sitio para ella. Las apps instaladas entregan la clave secreta al almacén seguro del sistema (Android Keystore, DPAPI en Windows, libsecret, llavero de iOS/macOS). Un navegador no tiene nada de eso: la clave vive en el almacenamiento del sitio y pasa por JavaScript en cada firma, al alcance de cualquier código que se ejecute en la página —una extensión con acceso a todos los sitios, un fallo de XSS en la app o en una dependencia, un despliegue manipulado— y de cualquier ladrón de información que copie el perfil del navegador. Tampoco hay un momento en el que verifiques el código una vez: un binario firmado se comprueba al instalarlo, mientras que una web sirve código nuevo en cada visita. Entra en la versión web con un firmante remoto (bunker NIP-46, Amber), y así la clave nunca llega al navegador, o úsala con una identidad desechable y guarda la de verdad en una app instalada.
- El correo puenteado vale lo que valga el bridge. Herkos verifica que un
mensaje marcado como procedente de un bridge realmente fue firmado por un
bridge que tienes configurado (o uno de los de serie). No puede verificar nada
sobre la dirección
From:tradicional que el bridge retransmite. - Los adjuntos los abre el sistema operativo. Herkos nunca lanza ficheros ejecutables ni de script, y pregunta antes de entregar al sistema cualquier otro adjunto que no pueda previsualizar, pero la aplicación que abre el fichero queda fuera de nuestro control.
Herkos Local Relay: qué protege y qué no
Herkos Local Relay guarda en tu dispositivo los eventos de tus apps, también los privados (borradores, listas privadas, los sobres que recibes). Esto es lo que lo protege y dónde está el límite, plataforma por plataforma. Los fallos de seguridad del relay se informan igual que los demás (arriba).
La base de datos va cifrada entera, el diario incluido (SQLite3 Multiple Ciphers, AEGIS-256). La clave son 32 bytes al azar creados en el dispositivo y guardados en el almacén seguro del sistema: el Keystore en Android, DPAPI en Windows, el llavero (libsecret) en Linux. No lleva una contraseña tuya, porque el relay tiene que arrancar solo. Sin la clave, el relay no arranca y lo dice: nunca abre ni crea una base sin cifrar, y nunca borra la que no puede abrir.
| Si… | Android | Windows | Linux |
|---|---|---|---|
| alguien copia el fichero de la base (una copia de seguridad, una carpeta sincronizada, una imagen del disco) | Protegido | Protegido | Protegido |
| te roban el aparato o el disco apagado | Protegido: la clave está en el Keystore | Protegido, salvo que sepa la contraseña de tu sesión de Windows: DPAPI protege la clave con ella | Protegido, salvo que sepa la contraseña de tu llavero (casi siempre, la de tu sesión) |
| otra cuenta de usuario del mismo aparato | Protegido | Protegido: DPAPI es por usuario | Protegido: el llavero es por usuario |
| otra app o programa que funciona con tu usuario | Protegido: Android aísla cada app y el Keystore solo da la clave al relay | No: DPAPI cifra por usuario, no por app; un programa que corre como tú puede pedir la clave igual que el relay | No: el llavero de tu sesión no separa unas apps de otras |
| un teléfono con root, o una herramienta que ejecuta código como la app | No | — | — |
| alguien tiene el aparato desbloqueado en la mano | Solo con el PIN o la huella del relay, si los pones | Igual | Igual |
| alguien lee la memoria del relay mientras funciona | No | No | No |
En escritorio, el límite de DPAPI y del llavero es el de cualquier programa: protegen frente a otros usuarios y frente a quien se lleva el disco, no frente a un programa malicioso que ya corre con tu usuario. Si te preocupa ese caso, lo que protege es el cifrado del disco del sistema (BitLocker, LUKS) junto con no ejecutar programas en los que no confías. En Linux sin llavero (sin Secret Service), el relay no arranca y lo explica: nunca guarda la clave en claro.
Quién entra, en el propio dispositivo. El relay escucha solo en
127.0.0.1, y cualquier app del dispositivo, o una página web del navegador,
puede llegar a esa dirección. Por eso:
- Una app tiene que emparejarse: aparece en la pantalla del relay y tú la apruebas (con el PIN o la huella, si los pusiste). Cualquier app puede ponerse cualquier nombre: aprueba solo si acabas de pedirlo desde esa app.
- Una página web se empareja siempre, y un emparejamiento vale solo desde donde se hizo: el de una app del dispositivo no abre nada a una página web, aunque firme con la misma clave.
- Una app emparejada solo lee y escribe los tipos de evento que le diste, y solo borra los que puede escribir. Revocarla la desconecta en el acto.
- Una app sin emparejar solo lee tus eventos públicos (que ya son públicos) y no escribe nada, salvo que enciendas el ajuste que deja entrar a las apps del dispositivo sin emparejar.
- Los eventos privados solo se entregan a quien demuestra con NIP-42 que tiene la clave a la que pertenecen, y un sobre, solo a su destinatario.
Lo que no protege, aquí:
- Una app maliciosa del dispositivo puede ralentizar el relay o hacerle gastar memoria. No puede leer lo privado por eso.
- Mientras el relay duerme o no funciona, el puerto queda libre. En Android se duerme tras 10 minutos sin conexiones; en escritorio, el puerto está libre mientras no lo arrancas. Otra app podría escuchar ahí y hacerse pasar por él. Las apps de Herkos comprobarán la clave del relay antes de enviarle nada privado; todavía no lo hacen, y hasta entonces ese es un límite real.
- En escritorio, otros usuarios del ordenador pueden conectarse como una app sin emparejar: leer tus eventos públicos y pedir emparejarse.
La red local, si la enciendes (viene apagada):
- Solo
wss://, con un certificado propio del relay; nuncaws://sin cifrar fuera del dispositivo. - Nada antes de autenticarse (NIP-42) con una clave de tu lista. Una conexión que no lo hace en 30 segundos se cierra, y la red local tiene un número de conexiones propio: nunca ocupa las de las apps del dispositivo.
- Una clave de la lista lee tus eventos públicos y los suyos privados, y solo escribe eventos firmados por ella. Quitarla la desconecta.
- El certificado solo vale para nombres de casa (
localhost,.local, direcciones privadas): aunque alguien robara su clave, no le serviría para firmar un dominio de Internet en los aparatos que lo instalaron.
Lo que no protege, aquí: quien está en la misma red ve que el aparato tiene un puerto abierto y cuánto tráfico pasa, aunque no lo que pasa; y si el aparato tiene una dirección pública (sin router en medio), ese puerto se ve desde Internet, aunque siga pidiendo una clave de tu lista.
Copias. La copia cifrada lleva contraseña (scrypt y XChaCha20-Poly1305): sin ella no la abre nadie, tampoco nosotros. La exportación en JSONL no va cifrada y lleva tus eventos privados en claro; la app lo avisa.
El bloqueo (PIN, y huella o Windows Hello) se pide al abrir la app, tras 30 segundos fuera, y para aprobar un emparejamiento. Es una barrera de conveniencia, como en Mail: no cifra nada. En Android, con PIN no hay capturas de pantalla ni miniatura en las apps recientes, y desde Android 12 ninguna ventana de otra app puede ponerse encima de la del relay mientras la usas.
Herkos Drive: qué protege y qué no
Herkos Drive guarda tus archivos en servidores Blossom y la lista de tus
archivos y carpetas en relays Nostr, las dos cosas cifradas en tu dispositivo.
Esto es lo que los protege y dónde están los límites. El detalle completo está
en spec-drive.md y en el modelo de amenazas amenazas-drive.md, en
packages/herkos_drive_protocol/; lo que ve cada relay y cada servidor, en la
política de privacidad. Los fallos de
seguridad de Drive se comunican igual que cualquier otro (arriba).
Lo que no pueden hacer los relays ni los servidores:
- Leer tus archivos o sus nombres. Cada bloque de un archivo va cifrado con AES-256-GCM con una clave propia de su revisión; los nombres, las carpetas, los tamaños, las fechas y las claves van sellados con XChaCha20-Poly1305 con la clave de la carpeta donde están. Nada sale del contenido: el mismo archivo subido dos veces da bloques distintos.
- Cambiar, intercambiar o mover algo sin que se note. Cada bloque se comprueba contra el manifiesto sellado en la entrada de su archivo, y cada entrada va firmada por la clave del volumen y sellada para su sitio (volumen, identificador y carpeta): un relay no puede hacer pasar una entrada por otra, ni un bloque por otro.
- Devolver una versión vieja. La app nunca acepta una entrada más antigua que la que ya tiene para el mismo identificador.
- Escribir como tú con solo la clave del volumen. Lo que escriben tus dispositivos lleva la marca del dueño, un HMAC con una clave que ningún enlace da; una entrada o un borrado sin ella no se acepta, y la app te avisa.
Lo que no protege:
- El patrón de tu Drive. Los relays pueden contar tus archivos y carpetas, ver la forma del árbol y cuándo cambia cada entrada; los servidores ven más o menos lo grande que es cada archivo (los bloques se rellenan a 64 KiB y las entradas a una potencia de dos). Cada relay y cada servidor ven tu dirección IP. Si eso te importa, usa Tor u Orbot en todo el sistema.
- Lo que alguien ya bajó. Quitar un enlace, o a una persona, da claves nuevas al momento a lo que podía abrir, así que no abre lo que añadas después; no puede recuperar lo que ya guardó.
- Un enlace que se filtra. Un enlace sin contraseña es la llave. El navegador puede guardarlo en su historial antes de que la página lo quite de la barra de direcciones. Para lo sensible, pon contraseña al enlace y mándala por otro camino, o comparte con la cuenta de la persona. Una contraseña débil se puede romper con tiempo: quien tiene el enlace puede probar sin conexión.
- La página
herkos.app/f/se ejecuta en el navegador de quien abre un enlace. Se sirve con una Content-Security-Policy estricta, Subresource Integrity y sin código de terceros, pero quien controle el alojamiento web podría servir otra página. Es el límite de toda página web que descifra en el navegador. - Quien tuvo la clave del volumen (la tuya, o la que da un enlace a una carpeta) puede seguir borrando los bloques que se subieron con ella, hasta que se vuelvan a subir. Puedes cambiar la clave del volumen (Ajustes → Clave del volumen): tus otros dispositivos la siguen solos.
- Tu dispositivo. La lista de archivos se guarda cifrada, con su clave en el almacén seguro del sistema; un archivo que bajas o abres se escribe en claro donde tú eliges. El PIN de Drive es una barrera de comodidad, como en Mail.
- Un ordenador cuántico, más adelante. Los bloques y los sellos son simétricos (AES-256, XChaCha20), pero tu localizador va cifrado con NIP-44 sobre secp256k1: quien lo guarde hoy y rompa secp256k1 mañana podría abrir el Drive entero.
Cómo se comprueba. Dos revisiones internas contra el modelo de amenazas (2 de noviembre de 2026) y sus arreglos; pruebas de lo que deja ver cada evento y cada bloque; fuzzing de todos los lectores de lo que llega de fuera (eventos, sellos, manifiestos, enlaces, copias). Aún sin auditoría externa: hay una prevista antes de la beta pública, y su informe se publicará entero. Drive todavía está en desarrollo.
Versiones con soporte
Las correcciones de seguridad se aplican a la última versión publicada. Dado el tamaño del proyecto, las versiones anteriores no se mantienen: actualiza antes de informar.