Histoire d’horreur en sécurité : exposition accidentelle de données personnelles
25 octobre 2021
0 minutes de lectureRien ne vaut une bonne histoire d’horreur… surtout quand il est question de développement logiciel et de sécurité. Après tout, qu’est-ce qui pourrait bien mal tourner quand on développe un logiciel ??? Et surtout, qu’est-ce qui pourrait mal tourner lorsque votre équipe et vous travaillez sur une petite application de R&D dont le financement est encore en attente…
Vous imaginez bien qu’une immense pression pour livrer des fonctionnalités à toute vitesse afin d’obtenir le financement de la prochaine période crée un terreau idéal pour une catastrophe annoncée. En particulier lorsqu’il n’y a pas de vision claire de l’objectif final du projet et que les idées changent d’un jour à l’autre.
Laissez-moi vous raconter mon histoire, où les choses ont mal tourné du point de vue de la sécurité. Comme ce petit projet de R&D mené à la cowboy faisait partie d’une grande institution, comparable à une banque ou à une compagnie d’assurance, les enjeux dépassaient largement ceux d’un simple petit projet.
Le projet
Le projet a commencé par une application mobile permettant de consulter des biens immobiliers, comme des immeubles et des maisons. La majeure partie de la logique système se trouvait côté serveur : nous avons donc créé une excellente architecture orientée services (microservices) en Java.
L’un des services était le serveur de profils. Chaque profil contenait un UUID généré aléatoirement et une liste de préférences. L’une des principales fonctionnalités permettait aux utilisateurs d’utiliser l’application de façon anonyme. Nous stockions donc l’UUID dans le stockage local de l’appareil et l’utilisions pour récupérer le profil sur le serveur. En résumé, le service ressemblait à ceci.

À un moment donné, l’idée est venue de permettre à un utilisateur de revendiquer un bien dans le système. C’est principalement utile lorsqu’il possède la maison ou l’immeuble. Le propriétaire pouvait alors enrichir la fiche du bien avec des photos et une description. Un bien ne pouvait être revendiqué que par un seul utilisateur.
Cette nouvelle fonctionnalité a entraîné deux changements cruciaux dans le contexte de cette histoire.
Nous avons créé un nouveau service appelé « MyHouse » pour permettre à un utilisateur de revendiquer une maison
Le service de profils devait être amélioré. Un utilisateur devait désormais pouvoir se connecter et revendiquer une maison. Nous avons donc ajouté une option d’inscription au service de profils existant.
Les services ressemblaient à ce qui suit : un objet MyHouse était associé à un profil utilisateur contenant l’UUID, et le profil pouvait désormais contenir une adresse e-mail.

Il est important de noter qu’on nous avait demandé de continuer à prendre en charge l’utilisation anonyme comme auparavant, et que cette fonctionnalité devait s’ajouter à ce qui existait déjà.
Le problème
Le nouveau service MyHouse disposait d’un point de terminaison permettant de répertorier tous les biens revendiqués. Celui-ci exposait l’objet MyHouse complet en JSON, y compris l’UUID du profil. Comme nous devions maintenir la fonctionnalité précédente, il était toujours possible de trouver un profil en connaissant simplement son UUID.

En bref, l’interface mobile n’avait pas du tout besoin de l’UUID. Cependant, en envoyant une simple requête HTTP et en disposant de l’objet MyHouse, on pouvait utiliser l’UUID dans un deuxième appel pour trouver le profil. Dès lors, il était possible d’associer l’adresse physique d’un bien à une adresse e-mail. Comme les adresses e-mail sont souvent de la forme firstname.lastname@provider.com (ou similaire), nous avions une fuite de données : il était possible d’associer une personne à une adresse physique. Oups, il s’agissait d’une fuite d’informations personnelles identifiables, ou PII.
La correction et les conséquences
Le problème a été signalé anonymement au service de sécurité de l’entreprise. Heureusement, une personne intègre a pris ses responsabilités et a effectué un signalement responsable. Une fois le problème compris, la correction a pris cinq minutes, déploiement en production compris. En ajoutant l’annotation @JsonIgnore au champ UUID du POJO MyHouse, nous avons empêché la sérialisation de ce champ en JSON : il n’était alors plus possible d’établir un lien entre un profil et une adresse physique.
D’un point de vue technique, vous pourriez arrêter la lecture ici. Pourtant, même si la correction était simple, les conséquences d’un tel incident sont extrêmement intrusives. Tout a commencé par une avalanche de questions sur l’incident :
Qui a été exposé ?
Depuis combien de temps ?
Quel est l’impact de cette fuite de données ?
Quelles données ont été divulguées ?
Qui a été victime de cette fuite ?
Pourquoi ne l’avons-nous pas évitée ?
Et ainsi de suite…
Toutes ces questions ont entraîné une quantité énorme de documents administratifs que mon équipe et moi avons dû remplir. Certaines réponses étaient évidentes, mais comme il s’agissait d’un projet de R&D mené sous forte pression, nous n’avions pas encore mis en place une journalisation adéquate. Il était impossible de savoir qui avait été victime de la fuite. Peut-être que des personnes malveillantes n’avaient même pas exploité la faille. Tout simplement, nous n’en savions rien.
Le pire, c’est que la direction nous reprochait maintenant des choses comme : « C’est honteux que nos ingénieurs ne soient absolument pas sensibilisés à la sécurité » ou « Cette équipe est incompétente, vous auriez dû vous en rendre compte ». En plus de l’énorme quantité de paperasse, les responsables ont commencé à tout microgérer sans avoir de connaissances pertinentes en développement ou en sécurité.
Les leçons à retenir
La première chose que nous avons faite a été de tout journaliser. Gérer un problème de sécurité est une chose, mais les conséquences et les questions qui s’ensuivent en sont une autre. Ensuite, nous avons examiné attentivement notre modèle de données pour vérifier si notre point de terminaison REST exposait des données dont l’interface n’avait pas besoin.
L’équipe d’ingénierie a également profité de cet incident pour résister aux exigences élevées et à la pression des responsables produit. Toutefois, la sensibilisation à la sécurité doit consister à intégrer la sécurité au processus de développement, et non à rejeter la faute sur les personnes. À mon avis, la bonne solution aurait été d’investir dans la culture et de choisir les outils adaptés pour faciliter le processus de développement. Peu après, j’ai décidé de quitter cette entreprise…
Suivez-nous sur Twitter (@snyksec) pour découvrir d’autres histoires d’horreur en sécurité comme celle-ci ! #31DaysOfSecurity
