Situation actuelle : PHP2Shell. Deux failles PHP critiques (CVSS 9.2) permettent d'exécuter du code malveillant sans authentification. Correctifs disponibles depuis le 21 octobre 2026.Ce qu'il faut faire maintenant →

Journaliser en sécurité : consigner les erreurs sans fuite de données

Les journaux aident au dépannage et à la forensique, mais deviennent vite eux-mêmes une fuite de données. Ce que les applications PHP devraient journaliser, ce qu'elles ne devraient jamais consigner et comment protéger les journaux.

État 7 min de lectureDéveloppement sécurisé

En bref : journaliser en PHP en tenant compte de la protection des données signifie : consigner intégralement les événements pertinents pour la sécurité, mais ne jamais écrire dans le journal les mots de passe, jetons, identifiants de session et données clients sensibles. Les erreurs vont dans le journal, pas à l'écran ; les journaux se trouvent en dehors du webroot et sont protégés contre toute modification. La durée de conservation des journaux se décide en connaissance de cause avec le délégué à la protection des données.

Entre préservation des traces et fuite de données

Après PHP2Shell, des médias spécialisés ont conseillé de conserver les journaux du serveur web à partir du 20 octobre 2026. Qui voulait le faire constatait souvent deux choses. Soit les journaux avaient depuis longtemps été archivés par rotation et supprimés. Soit ils contenaient des éléments qui n'auraient jamais dû s'y trouver : saisies complètes de formulaires, mots de passe de connexions échouées, clés d'API dans des URL.

Les deux sont un problème. Sans journaux, un incident ne peut guère être reconstitué. Avec trop de contenu, le journal devient lui-même une cible, car qui accède au serveur le lit volontiers. Une bonne journalisation se situe entre les deux : assez pour la recherche de traces, le moins possible de données à protéger.

Ce qu'une application PHP devrait journaliser

L'aide-mémoire OWASP sur la journalisation cite les événements importants pour la sécurité et la traçabilité. Pour des applications PHP typiques, ils se résument ainsi :

Dans le journal Pas dans le journal
connexions réussies et échouées mots de passe, y compris ceux saisis incorrectement
contrôles d'autorisation échoués identifiants de session en clair
modifications des comptes et des droits jetons d'accès et clés d'API
erreurs de contrôle des saisies identifiants de la base de données
téléversements, imports et exports données de paiement et bancaires
modifications de configuration, démarrage et arrêt données de santé et autres données particulièrement sensibles
erreurs d'exécution avec leur emplacement, sans données utiles contenus complets de formulaires

Chaque entrée devrait répondre aux questions quand, où, qui et quoi : horodatage, application et hôte, adresse source, identifiant d'utilisateur, nature de l'événement et résultat. Noms ou adresses e-mail peuvent souvent être masqués ou remplacés par un identifiant interne, sans perdre en utilité.

Deux sources de données non souhaitées dans le journal sont souvent négligées. La première, ce sont les URL : si un jeton, une clé de réinitialisation de mot de passe ou une adresse e-mail figure dans la chaîne de requête, elle atterrit automatiquement dans le journal d'accès du serveur web, dans les journaux de proxy et dans l'historique du navigateur. De telles valeurs relèvent du corps de la requête ou d'un en-tête, pas de l'adresse. La seconde source est le mode debug. En mode debug, les frameworks et extensions écrivent souvent des requêtes complètes, des requêtes de base de données et des variables d'environnement. Si ce mode reste actif après un dépannage, un fichier grossit à votre insu avec précisément les informations qu'un attaquant recherche. Après chaque dépannage, vérifiez que les sorties de debug sont de nouveau désactivées, et supprimez les fichiers ainsi produits.

Journalisation en PHP : les réglages de base

Le premier niveau est PHP lui-même. En production, les erreurs doivent être consignées mais pas affichées. Le journal se trouve en dehors du webroot, afin qu'il ne soit pas accessible par une URL.

; php.ini ou pool FPM pour la production
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/app-error.log

Pourquoi les erreurs visibles sont dangereuses est décrit dans Désactiver l'affichage des erreurs en production. Le lien entre erreurs et exceptions en PHP est expliqué dans Erreurs et exceptions en PHP.

Le second niveau est l'application. De nombreux frameworks utilisent pour cela une bibliothèque conforme au standard PSR-3 de PHP-FIG, qui définit une interface de journalisation uniforme. Ce n'est pas la bibliothèque qui compte, mais la discipline : choisir délibérément les données de contexte, au lieu d'écrire des requêtes ou des objets entiers dans le journal.

<?php
// Neutraliser et masquer les saisies avant de les journaliser
function logSicher(string $text): string {
    return mb_substr(str_replace(["\r", "\n"], ' ', $text), 0, 200);
}

function maskiereMail(string $mail): string {
    [$name, $domain] = array_pad(explode('@', $mail, 2), 2, '');
    return mb_substr($name, 0, 1) . '***@' . $domain;
}

$logger->warning('Anmeldung fehlgeschlagen', [
    'benutzer' => maskiereMail(logSicher($_POST['email'] ?? '')),
    'ip'       => $_SERVER['REMOTE_ADDR'] ?? '',
    // jamais : 'passwort' => $_POST['passwort']
]);

Injection dans les journaux et entrées manipulées

Si une application écrit des saisies sans filtrage dans le journal, un attaquant peut créer de fausses entrées avec des retours à la ligne. Cela brouille l'analyse et peut masquer des traces. L'aide-mémoire OWASP recommande des formats structurés comme JSON, la suppression ou l'encodage des retours à la ligne et une limitation de la longueur des saisies dans le journal.

La protection des journaux eux-mêmes est tout aussi importante :

  1. Stockage en dehors du webroot et avec des droits dont l'utilisateur du serveur web a besoin pour écrire, mais pas pour supprimer d'anciens fichiers.
  2. Copie sur un second système, par exemple via syslog sur une connexion chiffrée. Qui prend le contrôle du serveur ne doit pas pouvoir simplement effacer les traces.
  3. Restreindre l'accès en lecture et le journaliser lui-même. Les journaux contiennent presque toujours des données personnelles.
  4. Détecter la panne : si le journal reste soudain vide, c'est un signal d'alerte.
  5. Synchroniser l'heure : tous les serveurs obtiennent l'heure de la même source et écrivent un fuseau horaire non ambigu dans le journal. Sinon, les entrées du serveur web, de PHP et de la base de données se laissent difficilement assembler en chronologie après un incident.
Important

Un journal qui ne se trouve que sur le serveur compromis est un faible moyen de preuve. Une copie continue sur un système séparé est souvent, après un incident, la seule source fiable.

Décider en connaissance de cause de la conservation et de la protection des données

La durée pendant laquelle les journaux peuvent et doivent être conservés résulte d'une pondération entre intérêt de sécurité, minimisation des données et exigences légales ou contractuelles. L'art. 32 du RGPD exige des mesures techniques et organisationnelles adaptées au risque, notamment pour garantir durablement la confidentialité, l'intégrité et la disponibilité des systèmes ; la journalisation peut y contribuer. En même temps, les données personnelles ne doivent pas être conservées plus longtemps que nécessaire.

Fixez donc une durée par type de journal, notez la justification et accordez les deux avec votre délégué à la protection des données. Pour une enquête en cours, il peut être nécessaire de conserver des journaux au-delà de la durée normale. Cela devrait alors aussi être documenté. Cette page est une information générale et ne constitue pas un conseil juridique ; pour des questions concrètes, le délégué à la protection des données et l'avocat vous aident. La façon d'analyser les journaux après une attaque est montrée dans Analyser les journaux du serveur web après une attaque.

Comment PHP SOS aide-t-il concrètement ?

  • Nous vérifions vos journaux existants à la recherche de mots de passe, de jetons et d'autres données qui n'y ont pas leur place.
  • Nous configurons PHP et l'application de façon que les erreurs soient consignées mais pas affichées.
  • Nous mettons en place une copie protégée des journaux sur un système séparé.
  • Via la supervision de sécurité, nous analysons en continu les entrées pertinentes pour la sécurité et signalons les anomalies de façon compréhensible.

Conclusion : de bons journaux sont sobres dans leur contenu et généreux dans leur protection. Qui définit dès aujourd'hui ce qui est journalisé et ce qui ne l'est jamais dispose, en cas de crise, de traces exploitables et non d'une fuite de données supplémentaire.

Questions fréquentes

Les adresses IP peuvent-elles figurer dans les fichiers journaux ?

Les adresses IP peuvent être des données personnelles. Savoir si vous les stockez et pendant combien de temps dépend de la finalité et de la base juridique. Clarifiez l'étendue et la conservation avec votre délégué à la protection des données ; cette page ne constitue pas un conseil juridique.

Combien de temps faut-il conserver les journaux ?

Aussi longtemps que nécessaire et juridiquement admissible pour la sécurité et le dépannage, et pas plus. Après PHP2Shell, la presse spécialisée a recommandé de conserver les journaux du serveur web à partir du 20 octobre 2026. Fixez les durées en connaissance de cause et documentez-les.

Qu'est-ce que l'injection dans les journaux ?

Si une saisie contient des retours à la ligne ou des caractères de contrôle et qu'elle est écrite sans filtrage dans le journal, elle peut créer de fausses entrées. Cela fausse les analyses. Des formats structurés comme JSON et la suppression des retours à la ligne l'empêchent.

display_errors doit-il être désactivé en production ?

Oui. Les erreurs doivent aller dans le journal, et non dans la sortie destinée aux visiteurs. Des messages d'erreur visibles révèlent des chemins, des requêtes et parfois des identifiants.

Sources

Contact immédiat

Chaque heure compte. Écrivez-nous maintenant.

Décrivez brièvement votre système, votre version de PHP et ce que vous avez observé. Nous vous répondons, faisons le point et travaillons à distance jusqu'à la clôture et la documentation de l'incident.

Aide immédiate