Blog

On a passé toute l'app au crible. Voici tout ce qui n'allait pas.

Sécurité v1.8.0

TL;DR

Avant de proposer Nøbody sur d'autres stores, on a fait relire tout le code, ligne par ligne. La relecture a trouvé des choses que l'app promettait et ne faisait pas : pièces jointes non chiffrées, messages envoyés en clair quand les clés n'étaient pas prêtes, un mode Tor qui laissait fuir l'adresse IP, et un bug introduit par notre propre correctif de la v1.7.0 qui détruisait l'historique des conversations privées. Tout est corrigé dans la v1.8.0. Ce qui ne l'est pas encore est listé à la fin.

Une précision d'abord : une grande partie du code de Nøbody a été écrite avec un assistant de programmation IA, et cette relecture a été faite de la même façon. Ce n'est pas un audit par une entreprise de sécurité, et on ne le présentera jamais comme tel. C'est une relecture complète et systématique, dont on publie tous les résultats.

Le pire venait de nous

En juillet, la v1.7.0 a apporté la confidentialité persistante : chaque message a sa propre clé, utilisée une fois puis détruite. C'est le but. Mais l'écran de conversation, lui, redéchiffrait les 50 derniers messages à chaque ouverture. Une clé détruite ne déchiffre plus rien, et l'expéditeur n'a jamais la clé de ses propres messages. Résultat : au deuxième affichage, l'historique privé devenait une rangée de 🔒, et cette version remplaçait la copie locale.

Les messages perdus ainsi ne peuvent pas être récupérés — c'est la contrepartie même de la confidentialité persistante. On en est sincèrement désolés. Depuis la v1.8.0, le téléphone garde sa propre copie chiffrée de chaque message envoyé ou lu, et ne redéchiffre jamais un message déjà lu.

Ce que l'app promettait sans le faire

  • Pièces jointes. Seule l'étiquette « [photo] » d'un message était chiffrée ; la photo, le vocal ou le fichier partaient en clair. Maintenant chaque fichier est chiffré sur le téléphone avec sa propre clé AES-256-GCM, transmise dans le message chiffré, et les métadonnées des photos (position GPS, modèle d'appareil) sont retirées avant.
  • Envoi en clair. Si les clés d'une conversation n'étaient pas encore prêtes, le message partait en clair ; les transferts et les réponses aux stories aussi, toujours. Désormais rien ne part tant que le chiffrement n'est pas prêt.
  • Mode Tor. Activer Tor ne s'appliquait qu'aux connexions créées ensuite : le canal temps réel, les images et les vocaux continuaient d'utiliser votre vraie adresse IP. Maintenant l'app redémarre pour appliquer le réglage, tout passe par Orbot, et les notifications push sont coupées en mode Tor.
  • Du code Google. Le lecteur de QR codes utilisait Google ML Kit, avec son module d'envoi de statistiques. Il est remplacé par ZXing, libre : l'app ne contient plus aucun code Google, et pèse 13 Mo de moins.
  • Données sur le téléphone. L'historique déchiffré était stocké en clair. Il est maintenant chiffré avec une clé gardée par le Keystore Android, et la sauvegarde Android dans le cloud est désactivée.
  • Verrouillage. Le verrou ne couvrait pas un écran déjà ouvert, et le code PIN n'avait pas de vraie limite d'essais. Il couvre désormais tout, avec des blocages de plus en plus longs après les erreurs.
  • Promesses fausses retirées. La « sauvegarde chiffrée » envoyait votre phrase de passe au serveur : l'export est maintenant chiffré sur le téléphone. La double authentification n'était jamais demandée à la connexion : retirée. L'épinglage de certificat TLS n'existait pas : la mention est retirée. Les rapports de plantage partaient automatiquement : ils sont désormais désactivés par défaut.
  • Côté serveur. Les notifications push transportaient des pseudos ; elles ne contiennent plus rien d'identifiant. Les préférences de notification n'étaient jamais enregistrées : c'est réparé, et vous pouvez masquer vos accusés de lecture. Chaque contenu public peut maintenant être signalé, commentaires et stories compris.

Ce qui n'est pas encore réglé

  • Les groupes utilisent une clé partagée, sans confidentialité persistante.
  • Les tout premiers messages d'une conversation, avant le premier aller-retour, ne sont pas protégés contre le vol d'une clé d'identité (il faudrait X3DH).
  • Le serveur voit qui parle à qui, et quand — jamais le contenu des messages privés.
  • Le code du serveur n'est pas encore publié, et aucun audit externe n'a été fait.

Tout est détaillé dans SECURITY.md, et le code du client est sur Codeberg. Si vous trouvez autre chose, écrivez-nous : c'est exactement pour ça qu'on publie tout ceci.