Skip to Content

Chapitre 13.3 — PII, logs & minimisation

⏱️ TL;DR — Les données personnelles (PII : identité, email, mais aussi données sensibles comme la santé) sont un actif à protéger — et une obligation légale (RGPD, cours RGPD). Deux réflexes majeurs de dev. Minimisation : ne collecter, ne transmettre et ne conserver que le strict nécessaire — la donnée qu’on n’a pas ne peut pas fuiter. Ne pas fuiter dans les logs : c’est la fuite silencieuse la plus fréquente — un console.log(user) qui imprime un profil complet, un mot de passe ou un token dans un log, un objet d’erreur verbeux. On masque/exclut les données sensibles des logs, on ne renvoie au client que des DTO minimaux, et on traite chaque exposition de PII comme un incident (violation de données potentielle).

🎯 Objectifs

  • Reconnaître les PII (dont les données sensibles) et l’enjeu RGPD associé.
  • Appliquer la minimisation : collecter/transmettre/conserver le strict nécessaire.
  • Ne pas fuiter de PII ni de secrets dans les logs (masquage, exclusion).
  • Ne renvoyer au client que des DTO minimaux ; lier à la notion de violation de données.

PII : de quoi parle-t-on

Les PII (Personally Identifiable Information) — ou données à caractère personnel — sont toute information se rapportant à une personne identifiée ou identifiable : nom, email, identifiant, adresse IP, mais aussi des données sensibles (santé, handicap, opinions…) qui bénéficient d’une protection renforcée (cours RGPD). Pour un dev, la conséquence est double :

  • Sécurité : ces données sont ce qu’un attaquant convoite (revente, usurpation) ; les protéger relève de la confidentialité (Partie 1).
  • Légal : le RGPD impose une « sécurité du traitement » et transforme une fuite en violation de données avec obligations (notification sous 72 h si risque, etc. — Partie 15). Sécurité et conformité sont le même sujet ici (rappel Moodle, Partie 11).

Minimisation : la donnée qu’on n’a pas ne fuit pas

Le principe le plus puissant et le plus sous-utilisé : minimiser. Moins tu détiens de données, moins il y a à protéger, à fuiter, à notifier. La minimisation s’applique à trois moments :

  • Collecter le minimum : ne demande que les champs nécessaires à la fonctionnalité. Un formulaire d’inscription n’a pas besoin de la date de naissance « au cas où ». Chaque champ collecté est une responsabilité.
  • Transmettre le minimum : ne renvoie au client / aux tiers / aux logs que ce qui est nécessaire (voir DTO plus bas). Ne fais pas transiter un profil complet là où un id suffit.
  • Conserver le minimum : définir des durées de conservation et purger ce qui n’est plus utile. Une base qui accumule des années de données inutiles est une fuite plus grosse le jour venu.

💡 Réflexe — Avant de collecter, stocker ou transmettre une donnée personnelle, demande-toi : « en ai-je vraiment besoin, ici, maintenant ? ». Si non, ne la prends pas (ou ne la transmets pas). C’est la mesure de sécurité la plus rentable : la donnée que tu ne détiens pas ne peut être ni volée, ni fuitée, ni à notifier. La minimisation est autant une bonne pratique de sécurité qu’une obligation RGPD.

Ne pas fuiter dans les logs : la fuite silencieuse

La fuite de PII (et de secrets) la plus fréquente et discrète passe par les logs. On loggue pour déboguer, et sans y penser on imprime des données sensibles qui atterrissent dans des fichiers, des services de logs tiers, des dumps — souvent moins protégés que la base, et consultés par plus de monde.

Les vecteurs classiques :

// ❌ Fuites typiques dans les logs console.log('user', user) // imprime TOUT l'objet (email, hash, tokens...) logger.info(`login ${email} / ${password}`) // un MOT DE PASSE dans les logs (!) logger.error(err) // un objet d'erreur qui contient le corps de requete, des secrets app.use(morgan(':url')) // une URL avec un token en query string

Les parades :

  • Ne jamais logger de secrets (mots de passe, tokens, clés) ni de PII sensibles. Le mot de passe ne doit jamais apparaître dans un log — même pas « temporairement pour débuguer ».
  • Logger des identifiants, pas des contenus : préfère logger.info('login', { userId }) à imprimer l’objet user complet.
  • Masquer/rédiger (redaction) les champs sensibles : configurer le logger pour caviarder automatiquement les clés connues (password, token, authorization, email…) — beaucoup de loggers offrent une liste de champs à masquer.
  • Attention aux objets d’erreur : une exception peut embarquer le corps de la requête, des en-têtes (Authorization), des secrets. Ne loggue pas les erreurs brutes sans filtrage, et ne les renvoie pas au client (Partie 6).
  • Pas de secret/PII en URL : les URL sont loggées (proxy, serveur, Referer) — ne mets jamais un token ou une donnée sensible en query string (rappel Partie 2).
  • Protéger les logs eux-mêmes : accès restreint, durée de conservation, chiffrement si sensibles — ils contiennent potentiellement de la PII et relèvent donc aussi du RGPD.

⚠️ Piège — « Je logge l’objet complet, c’est pratique pour débuguer. » C’est la source n°1 de fuite silencieuse de PII et de secrets. Les logs sont exportés vers des services tiers, conservés longtemps, consultés par des équipes larges, et rarement chiffrés — bref, moins protégés que ta base. Un console.log(user) ou une erreur brute logguée peut exposer emails, hashes, tokens, corps de requêtes. Loggue des identifiants et des messages, pas des contenus sensibles, et configure la rédaction automatique des champs connus.

DTO : ne renvoyer au client que le nécessaire

Rappel de la Partie 10 : une réponse d’API ne doit contenir que les champs nécessaires à l’affichage, pas l’entité complète. Renvoyer un objet user brut (avec passwordHash, resetToken, champs internes) est une fuite — vers le client, mais aussi potentiellement vers les logs et les caches. On construit des DTO (objets de transfert) explicites :

// ✅ DTO : projection explicite, uniquement le necessaire function toUserDTO(u: User) { return { id: u.id, nom: u.nom, avatarUrl: u.avatarUrl } // pas de hash, token, email interne... }

C’est de la minimisation à la transmission : le client (et tout ce qui voit la réponse) ne reçoit que le strict utile.

🎯 Côté attaquant — L’attaquant collecte la PII partout où elle traîne : réponses d’API sur-exposées (entité complète), logs accessibles (un service de logs mal protégé, un fichier lisible), messages d’erreur verbeux, URL avec des données en query string, caches. Il sait que les données personnelles fuient plus souvent par négligence (log d’un objet complet, réponse trop riche) que par une attaque sophistiquée. Chaque endroit où une donnée personnelle apparaît « pour rien » est une prise — et une violation de données potentielle pour toi.

🧭 Sur FormaCampus — FormaCampus, qui manipule des données d’apprenants (parfois sensibles), applique la minimisation à tous les étages : collecte limitée aux champs nécessaires, durées de conservation définies (purge automatique), DTO explicites dans toutes les réponses d’API (jamais l’entité complète — pas de passwordHash, pas de champ interne). Les logs sont configurés avec rédaction automatique des champs sensibles (password, token, authorization, données de santé), ne contiennent que des identifiants (pas de contenus), sont à accès restreint, chiffrés et à durée limitée. Aucun secret ni mot de passe n’est jamais loggué. Cette discipline est à la fois de la sécurité et de la conformité RGPD : une exposition de PII y est traitée comme un incident (violation de données) à évaluer et, si besoin, notifier (Partie 15).

✏️ Exercices

Exercice 1 — Nettoie le logging. Repère et corrige les fuites dans ce code.

app.post('/login', (req, res) => { console.log('tentative login', req.body) // { email, password } const user = authenticate(req.body) console.log('user connecte', user) // objet user complet // ... })

✅ Solution

Deux fuites : (1) console.log('tentative login', req.body) imprime le mot de passe en clair dans les logs — inacceptable (un mot de passe ne doit jamais être loggué). (2) console.log('user connecte', user) imprime l’objet user complet (email, passwordHash, tokens, champs internes) → fuite de PII/secrets dans les logs. Correctif : ne logger que des identifiants et messages, jamais de contenus sensibles :

app.post('/login', (req, res) => { const user = authenticate(req.body) if (user) logger.info('login reussi', { userId: user.id }) // juste un id else logger.warn('login echoue', { email: maskEmail(req.body.email) }) // email masque, pas de mdp })

En complément : configurer le logger pour caviarder automatiquement les champs password/token/authorization, et ne jamais logger req.body/objets bruts sur des endpoints sensibles.

Exercice 2 — Minimisation. Un formulaire d’inscription à une newsletter demande : email, nom, prénom, date de naissance, adresse postale, numéro de téléphone. Comment appliquer la minimisation ?

✅ Solution

Pour envoyer une newsletter, la seule donnée nécessaire est l’email (éventuellement le prénom pour personnaliser). Le reste — nom complet, date de naissance, adresse postale, téléphone — n’est pas nécessaire à cette finalité : le collecter viole la minimisation (et le principe RGPD de limitation des finalités). Chaque champ superflu est une donnée de plus à protéger, à sécuriser, et à notifier en cas de fuite — pour rien. Application : ne demander que l’email (et au plus le prénom), retirer les autres champs du formulaire. Si certaines données sont nécessaires à une autre finalité (ex. facturation), les collecter séparément, au moment où c’est justifié, avec la base légale adéquate (cours RGPD). La donnée qu’on ne collecte pas ne peut pas fuiter.

🧠 Quiz de révision

1. Pourquoi la protection des PII est-elle à la fois sécurité et conformité ?

Parce que les PII relèvent de la confidentialité (actif à protéger, Partie 1) et du RGPD, qui impose la « sécurité du traitement » et transforme une fuite en violation de données avec obligations (notification, etc.). Une faille de sécurité sur des données personnelles est directement une violation à gérer légalement.

2. Qu’est-ce que la minimisation et à quels moments s’applique-t-elle ?

Ne détenir que le strict nécessaire, à trois moments : collecter (que les champs utiles), transmettre (DTO minimaux, pas de profil complet inutile), conserver (durées de conservation, purge). Principe : la donnée qu’on n’a pas ne peut pas fuiter — mesure de sécurité très rentable et obligation RGPD.

3. Pourquoi les logs sont-ils un vecteur de fuite majeur ?

Parce qu’on y imprime des données sans y penser (console.log(user), mot de passe, erreur brute, URL avec token), et que les logs sont exportés vers des tiers, conservés longtemps, consultés largement et rarement chiffrés — donc moins protégés que la base. Un objet complet loggué expose emails, hashes, tokens.

4. Comment éviter de fuiter des données dans les logs ?

Ne jamais logger secrets/mots de passe/PII sensibles ; logger des identifiants (userId) pas des contenus ; masquer/rédiger automatiquement les champs sensibles (password, token, authorization) ; se méfier des objets d’erreur bruts et des URL avec données en query ; et protéger les logs (accès, durée, chiffrement).

5. Qu’est-ce qu’un DTO et en quoi participe-t-il à la protection des PII ?

Un DTO (objet de transfert) est une projection explicite ne contenant que les champs nécessaires (ex. { id, nom, avatarUrl }), au lieu de l’entité complète. Il évite d’exposer les champs sensibles (passwordHash, tokens, données internes) vers le client/les logs/les caches — c’est de la minimisation à la transmission.


Fin de la Partie 13. Secrets et données sensibles sont sous contrôle : rien dans Git, stockage en vault, rotation, chiffrement bien géré, minimisation et logs propres. On sort de l’appli pour durcir son environnement : la Partie 14 — Durcir l’infra & le déploiement.

Last updated on