Skip to Content
RGPDPartie 9 — Sécurité des données9.5 — Journaux (logs) & atelier

Chapitre 9.5 — Journaux (logs) & atelier

⏱️ TL;DR — Le piège dev par excellence : balancer des données personnelles dans les logs — e-mails, IP, jetons, mots de passe, corps de requêtes entiers. Un log, c’est un traitement comme un autre : soumis à la minimisation, à une durée de conservation limitée, et à la sécurité. On distingue les logs de sécurité (traçabilité, à garder plus longtemps mais à accès restreint) des logs applicatifs (débogage, à nettoyer et purger vite). La bonne pratique : masquer/tronquer les données personnelles avant d’écrire. Ce chapitre montre un logger qui masque automatiquement, puis on met en sécurité FormaCampus avec une checklist récapitulative.

🎯 Objectifs

  • Comprendre pourquoi un log est un traitement soumis au RGPD.
  • Repérer et ne plus écrire les données personnelles à risque (e-mails, IP, jetons, mots de passe).
  • Distinguer logs de sécurité et logs applicatifs : finalités et durées différentes.
  • Appliquer le masquage / la troncature et coder un logger qui masque.
  • Dérouler la checklist de mise en sécurité de FormaCampus.

Un log est un traitement, pas un espace de gribouillage

Les logs sont l’angle mort des devs. On y écrit « pour déboguer », sans réaliser qu’un fichier de logs qui contient des e-mails, des IP et des identifiants est une base de données personnelles — souvent moins protégée que la vraie base, dupliquée chez l’hébergeur, dans un outil de supervision tiers, parfois exportée en clair. Une fuite de logs est une violation de données (Partie 10) à part entière.

Comme tout traitement, un log est soumis aux principes de l’article 5 :

  • Minimisation : n’écris que ce qui est nécessaire au diagnostic, pas « toute la requête au cas où ».
  • Limitation de la conservation : les logs ont une durée de vie limitée, puis on les purge (rotation automatique).
  • Sécurité (art. 32) : accès restreint, transport chiffré vers l’outil de logs, pas d’export sauvage.

⚠️ Piège — LE piège dev : logger.info("login", req.body) ou console.log(user) — et voilà l’e-mail, l’IP, parfois le mot de passe en clair ou un jeton de session écrits dans les logs, dupliqués partout, gardés des mois. On croit déboguer, on crée une fuite permanente. Le pire : les mots de passe et jetons, qui n’ont rien à faire dans un log, jamais, sous aucune forme.

Ce qu’on ne met jamais dans les logs

Liste noire, à connaître par cœur :

À ne jamais loggerPourquoiQue faire à la place
Mots de passe (même hachés)Secret d’authentificationNe rien logger du tout
Jetons (session, API, réinitialisation)Permettent l’usurpationRien, ou un identifiant technique non réutilisable
Numéros de carte / données bancairesFraudeRien (le prestataire de paiement gère)
Données sensibles (santé, art. 9)Divulgation intimeRien en clair
E-mails / téléphones en clairIdentifiants personnelsMasquer (m***@***.fr)
IP en clair (durée longue)Donnée personnelle (Breyer)Tronquer ou durée courte
Corps de requête/réponse completsContiennent tout le resteChamps strictement utiles, masqués

La règle mentale : avant d’écrire une ligne de log, demande-toi « est-ce que quelqu’un qui lit ce log apprend quelque chose sur une personne ? ». Si oui, minimise ou masque.

Logs de sécurité vs logs applicatifs

Tous les logs ne se valent pas ; leurs finalités diffèrent, donc leurs règles aussi.

Logs de sécuritéLogs applicatifs
FinalitéTraçabilité : qui s’est connecté, tentatives échouées, accès sensibles, actions d’adminDébogage : comprendre un bug, mesurer la performance
ContenuÉvénement, identité (souvent un identifiant technique), horodatage — pas le contenu des donnéesContexte technique minimal, sans données personnelles inutiles
ConservationPlus longue (pour enquêter après coup), mais justifiée et bornéeCourte : le temps de diagnostiquer, puis purge
AccèsTrès restreint, journaux protégésRestreint, nettoyés

Le fait qu’un log de sécurité soit gardé plus longtemps ne dispense pas de minimiser : on garde l’événement (« connexion réussie de l’utilisateur X à telle heure »), pas le contenu des données consultées. Et « plus longtemps » veut dire une durée déterminée et justifiée, pas « pour toujours ».

📚 Le texte — Il n’y a pas d’article du RGPD dédié aux logs ; ils relèvent des principes de l’article 5 (minimisation, limitation de la conservation) et de la sécurité de l’article 32. La CNIL a publié des recommandations sur la journalisation : tracer les accès pour la sécurité sans transformer les logs en fichier de surveillance disproportionné, avec des durées de conservation encadrées. Consulte sa recommandation à jour pour les durées — n’invente pas de chiffre.

Masquer et tronquer : la bonne pratique

La solution n’est pas de « ne plus rien logger » (on a besoin des logs) mais de masquer ou tronquer les données personnelles avant de les écrire. Quelques techniques :

  • Masquage : marie.dupont@ecole.fr devient m***@***.fr — on garde de quoi corréler sans exposer.
  • Troncature : garder une partie non ré-identifiante (par exemple tronquer une IP).
  • Identifiant technique à la place de l’identité : logger un user_id opaque plutôt que l’e-mail.
  • Liste d’autorisation de champs : on choisit ce qu’on log, au lieu de tout déverser puis masquer.

Un logger qui masque automatiquement

L’idéal est de centraliser le masquage dans un logger maison, pour ne pas dépendre de la vigilance de chaque dev à chaque appel. Exemple minimal en TypeScript :

// logger.ts — masque les données personnelles AVANT d'écrire const CLES_INTERDITES = ["password", "motDePasse", "token", "jeton", "authorization", "cookie", "carte"] function masquerEmail(v: string): string { const [avant, apres] = v.split("@") if (!apres) return "***" return `${avant.slice(0, 1)}***@***` } function masquerIp(v: string): string { // Tronque le dernier segment d'une IPv4 : 88.120.10.42 -> 88.120.10.x return v.replace(/(\d+\.\d+\.\d+)\.\d+/, "$1.x") } function nettoyer(valeur: unknown): unknown { if (typeof valeur === "string") { if (valeur.includes("@")) return masquerEmail(valeur) return masquerIp(valeur) } if (valeur && typeof valeur === "object") { const sortie: Record<string, unknown> = {} for (const [cle, val] of Object.entries(valeur)) { // On ne log JAMAIS un champ interdit : on le remplace par un marqueur if (CLES_INTERDITES.includes(cle.toLowerCase())) { sortie[cle] = "[masqué]" } else { sortie[cle] = nettoyer(val) } } return sortie } return valeur } export const logger = { info(message: string, contexte: Record<string, unknown> = {}) { // Le contexte passe TOUJOURS par le filtre avant d'être écrit console.log(JSON.stringify({ niveau: "info", message, ...(nettoyer(contexte) as object) })) }, } // Utilisation : même si on passe des données perso, elles ressortent masquées logger.info("connexion", { email: "marie.dupont@ecole.fr", ip: "88.120.10.42", password: "secret" }) // => {"niveau":"info","message":"connexion","email":"m***@***","ip":"88.120.10.x","password":"[masqué]"}

Le mot de passe ressort [masqué], l’e-mail et l’IP sont réduits. Le point clé : le filtre est central, appliqué à chaque log — on ne compte pas sur le fait que chaque dev pense à masquer à la main. À adapter (bibliothèque de logs réelle, champs de ton domaine), mais le principe est là : masquer par défaut, au point d’écriture.

💡 Réflexe — Traite tes logs comme du code de production sensible : liste d’autorisation des champs, masquage centralisé, rotation et purge automatiques (les logs ne s’accumulent pas indéfiniment), accès restreint, et vérification que ton outil de supervision tiers ne stocke pas ces logs en clair sans durée. Bonus : ajoute un test qui échoue si un champ interdit apparaît dans un log.

🧭 Atelier — Sécuriser FormaCampus

On rassemble les chapitres 9.1 à 9.5 en une checklist opérationnelle de mise en sécurité de FormaCampus. C’est le livrable concret : chaque case cochée est une mesure documentable au titre de l’article 32.

1. HTTPS partout (chiffrement en transit — 9.2)

  • HTTPS sur le site, l’API, l’espace organisme, les webhooks — y compris recette et interne.
  • Redirection http vers https, HSTS, aucun contenu mixte, certificats auto-renouvelés.

2. Mots de passe hachés (mesures techniques — 9.2)

  • Mots de passe apprenants, formateurs, admins hachés en argon2 (ou bcrypt), jamais en clair, jamais MD5/SHA-1.
  • Aucun mot de passe ni jeton stocké ou renvoyé en clair, nulle part.
  • Données santé (aménagements) chiffrées au repos ; clés hors du code ; pas de données bancaires stockées.

3. Accès cloisonnés (contrôle d’accès — 9.3)

  • Comptes nominatifs (zéro compte partagé), rôles RBAC, moindre privilège.
  • MFA sur admin, prod et outils d’infrastructure.
  • Cloisonnement : un formateur ne voit que ses groupes, un organisme que ses stagiaires (vérifié côté serveur).
  • Accès aux aménagements de handicap journalisé ; revue des accès trimestrielle.

4. Logs propres (journaux — 9.5)

  • Masquage centralisé des e-mails, IP, jetons ; jamais de mot de passe ni de jeton dans les logs.
  • Logs de sécurité et applicatifs séparés, durées de conservation définies, purge automatique.
  • Accès aux logs restreint ; outil de supervision tiers vérifié (pas de clair sans durée).

5. Sauvegardes & résilience (9.1–9.2)

  • Sauvegardes chiffrées, quotidiennes, et restauration d’essai testée régulièrement.
  • Plan de reprise minimal documenté.

6. Organisationnel & preuve (9.1–9.4)

  • Sensibilisation des équipes (hameçonnage, mots de passe), culture du signalement.
  • Checklist de départ (révocation immédiate), postes chiffrés, clauses de confidentialité.
  • Politique de sécurité écrite, mesures notées dans le registre (art. 30), procédure d’incident prête (cap sur la Partie 10).

🔒 Côté personne concernée — Tout ce chapitre se résume, pour un apprenant, à une phrase : « ce que je te confie ne traîne nulle part ». Pas son mot de passe dans un fichier de logs qu’un stagiaire de l’hébergeur pourrait lire, pas son e-mail exporté en clair dans un outil tiers, pas son aménagement de handicap visible dans une trace de débogage. Des logs propres, c’est du respect invisible — la personne ne le verra jamais, mais elle en subirait les conséquences si tu t’en dispensais.

✏️ Exercices

Exercice 1 — Nettoie la ligne. Un dev écrit logger.info("échec paiement", { email, ip, token, montant, carte }). Réécris cette ligne pour qu’elle reste utile au diagnostic sans exposer de données personnelles à risque.

✅ Solution

On retire le jeton et le numéro de carte (jamais dans un log), on masque l’e-mail et l’IP, on remplace l’identité par un identifiant technique, et on garde le strictement utile au diagnostic. Par exemple : logger.info("échec paiement", { userId: user.id, ip: masquerIp(ip), montant, code: "CARD_DECLINED" }). Le token et la carte disparaissent ; l’email est remplacé par un userId opaque (ou masqué si nécessaire à corréler) ; on ajoute un code d’erreur qui aide plus au débogage que les données personnelles. Idéalement, le logger masque déjà ces champs automatiquement, en filet de sécurité.

Exercice 2 — Quelle durée pour quel log ? Tu as (a) un log de sécurité « connexions et tentatives échouées » et (b) un log applicatif « détails de rendu d’une page ». Comment traites-tu leur conservation et leur contenu différemment ?

✅ Solution

(a) Log de sécurité : finalité traçabilité ; conservation plus longue mais déterminée et justifiée (pour pouvoir enquêter après un incident), accès très restreint ; contenu limité à l’événement (identifiant technique, horodatage, succès/échec), pas le contenu des données. (b) Log applicatif : finalité débogage ; conservation courte (le temps de diagnostiquer), puis purge automatique ; contenu minimal, sans données personnelles inutiles. Dans les deux cas : minimisation et durée bornée — « pour toujours » n’est jamais une réponse valable.

Exercice 3 — Audite le logger. On te donne un logger « qui masque ». Quels trois tests écris-tu pour être sûr qu’il protège vraiment ?

✅ Solution

(1) Champs interdits : passer un objet contenant password, token, carte et vérifier qu’ils ressortent [masqué] (jamais en clair). (2) E-mails et IP : passer un e-mail et une IP et vérifier qu’ils sont masqués/tronqués dans la sortie. (3) Récursivité : passer un objet imbriqué (données perso dans un sous-objet) et vérifier que le masquage s’applique en profondeur, pas seulement au premier niveau. Bonus : un test qui échoue le build si une chaîne ressemblant à un e-mail non masqué apparaît dans un log — pour attraper les régressions.

🧠 Quiz de révision

1. Pourquoi un log est-il soumis au RGPD ?

Parce qu’un log qui contient des données personnelles (e-mails, IP, identifiants) est un traitement et une base de données personnelles — souvent dupliquée et moins protégée. Il est donc soumis à la minimisation, à la limitation de la conservation (purge) et à la sécurité (art. 32). Une fuite de logs est une violation de données.

2. Que ne met-on jamais dans les logs ?

Mots de passe (même hachés), jetons (session, API, réinitialisation), données bancaires, données sensibles (santé) en clair. On masque les e-mails et les IP, on tronque ce qui peut l’être, on préfère un identifiant technique à l’identité, et on ne déverse pas les corps de requête complets.

3. Quelle différence entre logs de sécurité et logs applicatifs ?

Finalités différentes : traçabilité (sécurité) vs débogage (applicatif). Les logs de sécurité se conservent plus longtemps (durée justifiée et bornée), à accès très restreint, en gardant l’événement et non le contenu ; les logs applicatifs se conservent peu de temps, puis sont purgés. Dans les deux cas, minimisation et durée déterminée.

4. Quelle est la bonne pratique pour éviter de logger des données perso ?

Masquer / tronquer les données personnelles avant l’écriture, via un masquage centralisé dans le logger (pas la vigilance manuelle de chaque dev) : liste d’autorisation de champs, remplacement des champs interdits, e-mails et IP masqués, rotation et purge automatiques, accès restreint. Idéalement, un test qui échoue si un champ interdit apparaît.

5. Que contient la checklist de mise en sécurité de FormaCampus ?

HTTPS partout, mots de passe hachés (argon2) et données santé chiffrées, accès cloisonnés (RBAC, MFA, moindre privilège, journalisation des accès sensibles), logs propres (masquage, purge), sauvegardes chiffrées et testées, et le volet organisationnel (sensibilisation, offboarding, politique et procédure d’incident écrites). Chaque case est une mesure documentable au titre de l’article 32.


Chapitre suivant : Partie 10 — Violations de données — malgré toutes ces mesures, un incident peut survenir. On voit alors quoi faire : qualifier la violation, notifier la CNIL sous 72 h, communiquer aux personnes et tenir le registre des violations.

Last updated on