Incident de sécurité sur mon infolettre avec ListMonk — Les détails

Dans cet article, je vais te détailler tout ce qui s’est passé avec mon logiciel d’infolettre ListMonk. Tu découvriras ce que j’ai réalisé pour diminuer les impacts de l’incident de sécurité et respecter mes obligations légales.

Mercredi dernier, le 30 octobre, j’ai été avisé qu’une page du portail d’administration de ListMonk, mon logiciel d’infolettre, était accessible depuis Internet, sans authentification.

Le portail d’administration permet de voir la liste des abonné·es aux différentes listes de courriels, incluant le prénom et l’adresse courriel. On parle donc ici de données personnelles exposées publiquement.

Je te parle souvent de cybersécurité et de protection des renseignements personnels. C’est à mon tour de le vivre, alors je t’explique en détail comment j’ai traité cet incident de sécurité et appliqué ce que demande la loi 25.

Mise en contexte

j’utilise la plateforme d’autohébergement Yunohost, qui est basée sur la distribution Debian. Au moment de l’incident, la plateforme est à la version 11.3. Sur cette plateforme, j’ai installé le logiciel de gestion de listes de courriel ListMonk, qui est à la version 3.

Le mécanisme d’authentification pour accéder à la section administration repose entièrement sur les capacités de Yunohost et de son module d’authentification unique (Single sign-on) pour le proxy web nginx, appelé SSOwat.

C’est une mauvaise pratique de ne pas avoir implémenté de mécanisme d’accès dans l’application. Ça permet, s’il y a une faille dans la plateforme d’hébergement, l’accès public à l’application sans avertissement. De plus, ça empêche de pouvoir utiliser l’API de l’application sans devoir tout exposer.

La version 4 de ListMonk met en place un nouveau mécanisme d’authentification, mais cette version est encore en test et n’est pas disponible pour Yunohost.

Après avoir fait une enquête, j’ai maintenant une bonne idée de ce qui s’est produit. Les permissions de SSOwat dans le portail d’administration de Yunohost donnaient des accès visiteur à la section administration de l’application ListMonk, ainsi qu’à son API.

Points de terminaison de ListMonk

J’ai comparé cette installation avec les permissions par défaut d’une autre installation, et j’ai constaté que la configuration avait possiblement été modifiée par le passé sans que je m’en rende compte. Les dernières mises à jour sur le serveur ont eu lieu le 26 octobre, soit 4 jours avant. Je suppose que les données ont été accessibles sans authentification durant cette période.

Les risques d’incident de sécurité associés à l’autohébergement

L’autohébergement présente de nombreux avantages par rapport à l’utilisation de logiciels SaaS. Nous avons la possibilité de gérer où se trouvent les données, qui peut les utiliser, et rassurer nos utilisateurs·trices que leurs informations personnelles ne seront pas revendeurs ou utilisées dans des algorithmes sans leur consentement.

Ça permet aussi de choisir quels logiciels on utilise, quelle version, et quelle configuration. Bref, ça donne beaucoup de libertés.

Mais justement, beaucoup de libertés, ça vient aussi avec des responsabilités et une gestion des risques. C’est nous qui devons choisir les logiciels, les évaluer selon plusieurs critères, les installer, les configurer et les mettre à jour.

Les logiciels viennent sous plusieurs formes: des logiciels commerciaux qui ont une version communautaire. Des projets de grande envergure ou avec un historique de plusieurs décennies. Des petits nouveaux qui sortent des universités et des startups. Et, parfois, des projets personnels qui gagnent rapidement en popularité, sans nécessairement avoir les ressources nécessaires pour leur évolution en toute sécurité.

ListMonk, un projet personnel devenu une étoile de GitHub

La dernière situation que j’ai évoquée, le projet personnel qui gagne rapidement en popularité, est aussi celle qui présente le plus de risques de sécurité applicative (AppSec).

C’est le cas pour ListMonk. Développé à temps partiel par un seul développeur principal et un petit groupe de contributeurs·trices, c’est un projet qui évolue lentement, avec une ou deux livraisons majeures par année. La mise en place de fonctionnalité a primé sur la sécurité, comme pour beaucoup de logiciels, pour se construire une base d’adoption.

Listmonk est un logiciel bien conçu au niveau des fonctionnalités. Il permet de:

  • Gérer plusieurs listes avec la même base d’abonné·es
  • Faire des campagnes et des courriels transactionnels
  • Gérer la vie privée et les droits des sujets de données
  • Éditer les modèles et les contenus directement en Markdown ou en HTML, sans devoir gosser avec des éditeurs par blocs.

Bref, c’est un logiciel que j’aime et que je tiens à continuer à utiliser. Mais, pour cet incident, j’ai dû le mettre sur la voie de garage pour trouver ce qui ne fonctionnait pas, et utiliser temporairement une solution de rechange.

La gestion de l’incident de sécurité en étapes

Quand on gère un incident de sécurité, ça nous prend quelques outils pour se simplifier la tâche. Donc, je reçois un signalement comme quoi une page d’administration de mon infolettre est indexée sur Google.

1. Exporter la liste de contacts

La principale valeur d’une infolettre, c’est notre liste de contacts. Donc, ce que j’ai fait, c’est exporter chacune de mes listes dans un fichier CSV. Ça allait me permettre de m’installer ailleurs, et surtout, de communiquer l’incident, comme le demande la loi.

2. Fermer le service qui a causé l’incident de sécurité

La première chose à faire, c’est fermer le service. J’ai donc mis le service hors-ligne en faisant une sauvegarde et en le désinstallant du serveur. Yunohost permet ça, ça se fait en deux clics dans l’interface web.

J’ai aussi téléchargé ma sauvegarde de l’application pour avoir une version disponible hors-ligne si je veux y faire des vérifications.

3. Faire la désindexation du sous-domaine de Google

J’ai fait une demande de désindexation chez Google Search Console des deux noms de domaines qui sont connectés à l’application. C’est un service essentiel pour tout le monde qui a un site web, alors si ce n’est pas fait, je te conseille de t’y inscrire et de le configurer. Si ton site est géré par une autre entreprise, tu devrais quand même y avoir accès, ainsi qu’à ton registraire de domaine.

J’ai ensuite vérifié si le domaine était indexé sur d’autres moteurs de recherche, dont Bing, DuckDuckGo et Ecosia. Ce n’était heureusement pas le cas. J’ai aussi confirmé le tout avec le métamoteur SearxNG qui est installé sur mon serveur.

4. Mettre le site web en maintenance

J’ai mis mon site web transactionnel en maintenance, le temps de désactiver tous les formulaires qui pointaient vers mon infolettre et mettre en place des liens temporaires vers mes produits gratuits en téléchargement direct.

J’ai aussi arrêté tous mes workflows d’automatisation qui se connectent à ListMonk dans mon logiciel d’automatisation n8n.

Lorsqu’on gère un incident de sécurité, mettre les services en mode maintenance est une très bonne pratique. On veut éviter d’avoir encore plus de problèmes à gérer !

5. Rotation des clés API de mon fournisseur SMTP PostMark

Comme la clé API de PostMark est aussi dans la section administration de ListMonk, j’ai été sur ce service et j’ai fait révoquer la clé que j’utilisais, pour la remplacer par une nouvelle.

J’ai ensuite configuré la nouvelle clé dans mon Nextcloud et mon Moodle pour que leurs courriels s’envoient correctement. Je l’ai aussi mis à jour dans n8n pour que les automatisations fonctionnent bien quand j’allais les repartir.

Lorsqu’on utilise des services externes, tel que des SaaS, avec des intégrations qui demandent des clés API, c’est toujours une bonne pratique de faire une rotation de clés après un incident de sécurité.

6. Déménager temporairement

Tout coach mindset cheezy te dira, moyennant un léger supplément, que tout échec est une opportunité. J’avais dans ma bucket list de tester Cakemail, un logiciel d’infolettre québécois. Voici donc une excellente raison de le faire, et peut-être de l’adopter, qui sait ! (spoiler: mouais … non !)

Mais, ça ne s’est pas passé comme prévu. Leur système d’importation est pourri et plein de bogues, et chaque importation de liste écrasait les métadonnées sur les contacts partagés. Donc, j’ai dû faire un peu de code pour m’en sortir. Si tu dois faire du code pour importer des données dans un logiciel qui est no-code, c’est pas bon signe.

Donc, je ressors un peu mon Python et je convertis mes listes dans une grosse table avec des indicateurs vrai ou faux pour chacune des listes, que je mets sous forme d’attribut. Chaque attribut deviendra un champ additionnel dans le profil de l’abonné·e sur lequel je pourrai filtrer pour choisir le bon segment. C’est pas terrible, mais ça dépanne.

Avoir des compétences de base de programmation est vraiment un atout pour se remettre rapidement sur pied après un incident de sécurité. Le no-code, c’est facile, mais coder, c’est vraiment plus rapide, surtout avec les outils d’IA générative qui sont quand même bons pour faire du code facile.

7. Envoyer la notification d’incident de sécurité

Tu pourrais avoir tendance à penser qu’il faut aviser les gens en premier, mais ce n’est pas le cas. Il faut régler le bobo avant. Une fois qu’on est fonctionnel et que le danger n’est plus présent, on peut faire une déclaration.

J’ai donc envoyé un courriel à tous les gens qui ont leurs coordonnées dans mon logiciel de courriel. Ce n’est pas seulement mes abonné·es, mais aussi ma clientèle. Donc, un peu plus de 500 personnes. Ce qui fait que je passe au forfait payant sur Cakemail. Je prends seulement un mois pour tester. Je vais ensuite prendre une note dans mon gestionnaire de tâches de l’annuler pour ne pas l’oublier.

Quand on envoie une notice d’incident de sécurité, on explique ce qui est arrivé, si les gens doivent prendre des mesures pour se protéger, et ce qui n’est pas affecté. On informe, on rassure et on se rend disponible.

Ce n’est pas un exercice de relations publiques. Ce n’est pas le temps d’embellir les choses. Tu as fait une connerie, assume, et les gens vont apprécier ton honnêteté. Les gens lisent de la bouette tous les jours sur les réseaux sociaux, ils n’en ont pas besoin de ta part.

8. Déclarer l’incident de sécurité sur mon site web

Avec la loi 25, toutes les entreprises doivent avoir un registre des incidents de sécurité qui concernent des données personnelles. Tu peux mettre ça sur ta page de politique de confidentialité ou sur une page dédiée. Ce n’est pas tant important, tant que c’est pas caché quelque part sur ton blogue.

Ce que tu mets à cet endroit est un résumé à l’intention du public, pour qu’ils sachent qu’il t’est arrivé quelque chose et que tu t’en es occupé.

En gros, il faut mettre les champs suivants:

  • Date de découverte de l’incident: la date où tu t’en es rendu compte
  • Type d’incident: ce qui s’est passé
  • Renseignements visés: les renseignements qui sont dans le logiciel impacté. Si t’as déjà fait ton travail d’inventaire des données, t’as déjà cette information pas trop loin.
  • Support ou logiciel: quel système informatique est visé? Est-ce un logiciel, ou du matériel informatique ?
  • Nombre de personnes visées: une idée de grandeur pour évaluer l’impact. Mettre plus que pas assez ici.
  • Mesures mises en place depuis l’incident: tout ce que tu as fait jusqu’à maintenant.

Ça fait que j’ai fait mes devoirs, et j’ai rempli (un peu le cœur à l’envers) la première ligne de mon tableau.

9. Trouver le bobo

La situation ici est particulière parce que je suis mon hébergeur web ! Je voulais donc comprendre ce qui s’était passé plus en détail. J’ai donc installé ma sauvegarde sur un autre serveur pour voir quel était le problème de configuration. j’ai aussi comparé avec une autre installation du même logiciel, pour constater quel le bogue n’était pas présent à cet endroit.

J’avais donc affaire à un bogue de configuration et non pas dans le logiciel en tant que tel. Le logiciel a un problème de conception important, mais ce n’est pas ce qui est le plus important dans l’histoire pour l’instant.

Je me retrouve donc avec un problème d’authentification qui ne se fait pas sur un point de terminaison de mon application. En fait, et je le découvrirai plus tard, deux points de terminaison.

Dans Yunohost, l’authentification est gérée par un annuaire LDAP et par une couche d’authentification liée au serveur nginx nommée SSOwat.

C’est de logiciel qui est mal configuré. En fait, dans le portail de gestion des groupes, je remarque que la permission Listmonk (admin) est donnée au groupe visiteur et non au groupe administrateur, ainsi que Listmonk (API). Alors que cela devrait seulement être le site web qui est accessible aux visiteurs et visiteuses, pour pouvoir s’inscrire, se désinscrire, voire les images et accéder aux archives.

Les permissions Visiteurs sont la source de cet incident de sécurité.

Si je change les permissions, j’ai un problème de CORS bizarre que je n’avais pas venu venir. Sur ce serveur, il n’y a pas de règles CORS de configurée. Je décide donc d’essayer autre chose.

10. Mise à jour du serveur

Le hasard fait parfois bien les choses. ListMonk a une nouvelle version en préversion disponible, la version 4, qui inclus une refonte complète de l’authentification. Cependant, cette version n’est pas encore disponible pour Yunohost. Mais … mais, Yunohost 12 vient juste de sortir !

Pourquoi, tant qu’à être dans la gestion de crise, ne pas faire de mises à jour un vendredi soir ?

C’est parti ! J’ai fait une première mise à jour du serveur de mon site web. C’est celui avec le moins d’applications, donc le moins de risques. Je vais une sauvegarde complète, je la télécharge et je lance la migration. Une heure plus tard, tout s’est bien passé, je redémarre puisque j’ai changé de version de Debian (je n’avais pas redémarré depuis 314 jours !), et tout fonctionne !

Je décide donc de migrer ListMonk sur ce serveur à la place. C’est une petit serveur, mais ListMonk c’est vraiment tout petit ! La restauration de la sauvegarde fonctionne du premier coup. Je vais changer le DNS pour l’adresse IP de ce serveur, et tout fonctionne comme avant. Le bogue d’authentification n’est plus là, pas d’erreurs CORS bizarres. Tout va bien. Mais …

11. Déménager mon outil d’automatisation

En refermant la porte sur le portail d’administration et sur l’API, mes automatisations avec n8n (similaire à Make et Zapier) ne fonctionnaient plus. Comme la sécurité est fournie par SSOwat, je ne peux pas passer à travers en utilisant directement les fonctionnalités de connexion HTTP de l’outil.

Je dois automatiser directement depuis le serveur, en utilisant le port interne de l’application, qui n’est pas visible depuis le web.

C’est donc un 2e déménagement, celui de n8n. Heureusement, les transferts d’applications sur Yunohost se font facilement, avec des archives et l’utilisation de SFTP. J’utilise Filezilla pour ça. Une fois l’archive transférée, la restauration se fait essentiellement en quelques clics.

Donc, je me retrouve avec un serveur tout minuscule (un seul coeur, 2 Go de RAM) avec deux nouvelles applications. Heureusement, elles ont des besoins très limités en ressources, alors souhaitons que ça dure !

Conclusion: la préparation a une énorme valeur

Si j’ai pu rapidement gérer cet évènement, c’est que j’avais fait mon travail en amont.

  • Je connais mes logiciels et mon serveur d’autohébergement.
  • J’avais un plan de secours facile à mettre en place.
  • J’avais documenté toutes les données personnelles présentes dans mon entreprise.
  • J’avais un plan précis à suivre pour me permettre la continuité de mon infolettre.
  • J’ai des sauvegardes régulières de toutes mes données.
  • J’étais en confiance. Je savais exactement ce que je devais faire. Ce qui est primordial dans un moment stressant, surtout quand on tient à cœur à la sécurité.

Un dernier conseil pour la route. Évite Cakemail. Ça manque de sérieux. Leur séquence d’accueil par courriel n’a même pas de certificat HTTPS pour les liens de désinscription.

Tu aimerais ça, toi aussi, pouvoir faire face à des évènements comme celui-là ? Tu veux mettre en place le plus de mesures possibles pour éviter les dommages à ton entreprise ?

J’ai ce qu’il te faut !

Mon programme Pleine Confiance regroupe tous mes tutoriels et outil pour sécuriser ton entreprise et le hamster dans ta tête.

Je t’offre aussi un accompagnement en 6 séances pour qu’on fasse tout ça ensemble !

Pleine confiance 🛡️🧘

Cybersécurité, loi 25 et réputation web

Tout ce que tu as besoin de savoir et mettre en place pour avoir la paix !

Tu vas cliquer sur le mauvais lien éventuellement 🫢.
Je veux te préparer à ça.

Tu seras en mesure de protéger les données de ton entreprise et de ta clientèle et ne pas devenir victime des pirates du web.

Je veux que ton entreprise soit en sécurité dès maintenant.

Pleine Confiance, c’est pour ajouter des vies à ta business, comme dans une game de Mario Bros.

Mais sans avoir à te péter la tête sur des briques ni devoir prendre des champignons verts !

Disponible en mode autodidacte ou accompagné !