Module B06

Logging sécurisé & Audit

OWASP A09 — ce qu'il faut logger, ce qu'il ne faut jamais logger, détection d'anomalies.

01 OWASP A09 — Security Logging Failures

OWASP A09 (2021) — "Security Logging and Monitoring Failures" — identifie l'absence ou l'insuffisance de logging comme une vulnérabilité critique. Sans logs, il est impossible de détecter une attaque, d'y répondre, et d'en analyser les causes.

Évènement critique à loggerInformations à inclure
Tentative de login échouéetimestamp, IP, user-agent, email/username tentés
Login réussitimestamp, IP, user-agent, userId
Changement de mot de passetimestamp, IP, userId, source (user/admin/reset)
Accès refusé (403)timestamp, IP, URL, userId, raison
Erreur de validation JWTtimestamp, IP, erreur, token tronqué
Suppression/modification de données sensiblestimestamp, userId, ressource, ancienne valeur
Rate limit atteint (429)timestamp, IP, endpoint, compteur

02 Ce qu'il ne faut jamais logger

// ❌ JAMAIS logger :
logger.info({ password: req.body.password });    // Mot de passe en clair
logger.info({ token: req.headers.authorization }); // Bearer token complet
logger.info({ card: req.body.cardNumber });        // Numéro de carte
logger.info({ ssn: user.socialSecurityNumber });   // Données personnelles sensibles
logger.info({ secret: process.env.JWT_SECRET });   // Variables d'env
logger.info(`DB connected: ${process.env.DATABASE_URL}`); // URL avec credentials

// ✅ Ce qu'on peut logger :
logger.info({ userId: user.id, action: 'login', ip: req.ip });
logger.warn({ userId: user.id, action: 'password_change', source: 'user' });
logger.error({ code: err.code, message: err.message }); // Pas le stack trace en prod
⚠️ Masquer les données sensibles dans les logs : card: '****1234', token: token.substring(0,10) + '...'

03 Niveaux de log et structure JSON

const pino = require('pino');
const logger = pino({
  level: process.env.LOG_LEVEL || 'info',
  redact: ['req.headers.authorization', 'req.body.password', '*.creditCard'], // Auto-redact
  formatters: {
    level(label) { return { level: label }; }
  }
});

// Log structuré JSON
logger.warn({
  event: 'auth.login_failed',
  ip: req.ip,
  userId: req.body.email,
  userAgent: req.headers['user-agent'],
  timestamp: new Date().toISOString(),
}, 'Tentative de connexion échouée');
NiveauUsageExemple
fatalCrash de l'applicationDB inaccessible
errorErreur critique non récupéréeException non catchée
warnComportement suspectLogin échoué, 429
infoÉvènements normaux importantsLogin réussi, démarrage
debugDétails de debugDev uniquement
traceTrace complèteDiagnostic performance

04 Détection d'anomalies via les logs

Les logs permettent de détecter des patterns d'attaque en analysant les volumes, fréquences et séquences d'évènements.

// Middleware de sécurité — comptage des échecs
const failedLogins = new Map();

app.post('/auth/login', (req, res, next) => {
  const key = req.ip + ':' + (req.body.email || '');
  const attempts = (failedLogins.get(key) || 0) + 1;
  failedLogins.set(key, attempts);

  if (attempts >= 5) {
    logger.warn({ event: 'brute_force_detected', ip: req.ip, attempts, key },
      'Brute force potentiel');
  }
  next();
});
PatternIndicateurSeuil alerte
Brute force login5+ 401 depuis même IP/email en 15min→ Block IP + alerte
Scan de routes10+ 404 depuis même IP en 1min→ Rate limit + log
ExfiltrationVolume de données > X fois la moyenne→ Alerte SIEM
Privilege escalationAccès ressource admin par user normal→ Alerte immédiate
Token abuseMême token utilisé depuis 2 IPs différentes→ Invalidation token

05 Log management en production

StackComposantsUsage
ELK StackElasticsearch + Logstash + KibanaAnalyse, visualisation, alertes
Grafana LokiLoki + Promtail + GrafanaAgrégation légère, corrélation métriques
DatadogAgent Datadog + APM + LogsSaaS, APM intégré, alertes
CloudWatchAWS CloudWatch Logs + InsightsAWS natif, serverless
SplunkIndexer + Search HeadEnterprise, SIEM

Rétention et conformité

# Logs de sécurité — conservation minimum recommandée
Authentication events: 12 mois (RGPD, PCI-DSS)
Access logs: 90 jours
Error logs: 30 jours
Audit trail: 7 ans (comptabilité, compliance)

# Ne jamais purger les logs d'incident avant investigation
💡 Log injection : un attaquant peut injecter des newlines dans ses inputs pour créer de faux logs. Toujours échapper ou encoder les inputs avant de les logger.