SOC managé - surveillance continue  ·  veille cyber : CERT-FR / CISA / NVD  ·  réponse à incident en priorité
Tous les pas à pas

Exploitation · Tuto

Log4Shell (CVE-2021-44228) : ce que c'est, comment ça marche, comment corriger.

Vérifié le 4 septembre 2026 Sources Apache Log4j, CISA, HeroDevs (recoupées ce jour) À revoir avant septembre 2027

En décembre 2021, une seule ligne de texte a suffi à mettre en alerte des équipes de sécurité dans le monde entier. Cette ligne ressemble à ${jndi:ldap://...}, et la faille qui l'exploite s'appelle Log4Shell (référence officielle CVE-2021-44228). Elle touche Log4j, une bibliothèque Java utilisée par une quantité colossale d'applications pour écrire leurs journaux d'activité (les « logs »).

Ce guide explique la faille en partant de zéro - sans supposer que vous connaissiez Java - puis détaille très précisément comment vérifier si vous êtes concerné et comment corriger. Il n'explique pas comment fabriquer une attaque : ce que vous avez besoin de savoir pour vous défendre, ce n'est pas comment attaquer, c'est comment le mécanisme fonctionne et comment le fermer.

En résumé

  • Log4Shell (CVE-2021-44228) tient à un principe simple : une donnée fournie par l'extérieur a été traitée comme une instruction. C'est la même famille de défaut que l'injection SQL.
  • L'attaquant n'a besoin d'aucun compte : il place le motif n'importe où qui finira dans un journal - un nom à l'inscription, un champ de recherche, un en-tête envoyé par son navigateur.
  • La chaîne va jusqu'à l'exécution de code à distance, la catégorie de faille la plus grave : elle donne la main sur la machine, pas seulement sur une donnée.
  • Trois vérifications dans l'ordre : chercher le fichier log4j-core, inspecter l'arbre des dépendances (c'est là que se cachent les dépendances indirectes, le cas le plus fréquent), et ne pas s'arrêter à une première réponse négative.
  • Version cible selon Java : 2.17.1 minimum pour Java 8 et au-delà, 2.12.4 pour Java 7, 2.3.2 pour Java 6. Trois autres CVE découvertes ensuite se corrigent en même temps.
  • Si l'application ne peut pas être reconstruite : retirer la classe JndiLookup de l'archive existante. La variable d'environnement souvent citée ne protège pas contre toutes les variantes - c'est un pansement, jamais une solution.
  • La vraie leçon : le jour de la divulgation, la question n'était pas « comment corriger » mais « où ai-je du Log4j ? ». Cinq ans après, environ 12 % des applications Java tournent encore sur une version vulnérable.

1. Qu'est-ce que Log4Shell, en une image

Imaginez un centre de tri du courrier. Une machine ouvre chaque enveloppe, lit ce qui est écrit, et le recopie dans un grand registre - c'est le travail de Log4j : journaliser ce qui se passe (une connexion, une erreur, une recherche…).

Le problème : sur les versions concernées, si le contenu d'une enveloppe ressemble à une instruction plutôt qu'à un simple texte, la machine l'exécute au lieu de la recopier. Et l'une de ces instructions possibles veut dire : « va chercher un colis chez telle adresse et charge-le tel quel, sans le vérifier ». Le colis, dans ce cas, est un morceau de programme - et la machine l'exécute.

Le courrier arrive ${jndi: ldap://x} Log4j lit et interprete portail ouvert par la charge Serveur pirate "prends ce paquet" classe Java renvoyee Le tri du courrier ouvre par erreur une enveloppe qui contient, au lieu d'un texte, une instruction : "va chercher un colis chez un inconnu et charge-le tel quel".
Log4Shell - le tri du courrier qui obéit à une instruction cachée

Vu de l'extérieur, un attaquant n'a besoin de rien de compliqué : il place ce texte spécial n'importe où qui finira dans un journal - le nom qu'il choisit à l'inscription, un champ de recherche, un en-tête technique envoyé par son navigateur. Il n'a même pas besoin d'un compte sur votre système. Il compte simplement sur le fait qu'une application, quelque part dans votre organisation, va journaliser cette entrée avec une version vulnérable de Log4j.

2. Comment ça fonctionne, un peu plus en détail

Log4j sait interpréter des motifs spéciaux appelés des lookups, notés ${...}. Ils servent normalement à des choses utiles - insérer la date, une variable d'environnement, etc. Le lookup jndi permet, lui, d'aller chercher une ressource ailleurs sur le réseau (LDAP, RMI…) - une fonctionnalité légitime, prévue pour des usages d'entreprise anciens, mais jamais censée s'activer sur un texte fourni par un inconnu.

La chaîne de conséquences est courte : 1) une donnée que l'utilisateur contrôle finit dans un appel de journalisation, 2) Log4j y reconnaît le motif ${jndi:...} et l'interprète, 3) il contacte le serveur indiqué dans la charge, 4) ce serveur répond en désignant où trouver un objet à charger, 5) l'application charge et exécute cet objet. C'est ce qu'on appelle une exécution de code à distance (RCE) - la catégorie de faille la plus grave qui existe, parce qu'elle donne à l'attaquant la main sur la machine, pas seulement sur une donnée.

Le cœur du problème tient en une phrase, valable bien au-delà de Log4j : une donnée fournie par l'extérieur a été traitée comme une instruction. C'est la même famille de défaut que l'injection SQL - la machine confond « ce qu'on lui raconte » et « ce qu'on lui ordonne ».

3. Savoir si vous êtes concerné

Trois vérifications, de la plus simple à la plus fiable, à faire dans cet ordre :

  • a. Chercher le fichier lui-même. Log4j se présente comme une archive Java (un fichier .jar). Sur un serveur Linux :
    find / -name "log4j-core-*.jar" 2>/dev/null
    Le nom du fichier contient le numéro de version, par exemple log4j-core-2.14.1.jar. Si le numéro est inférieur à 2.17.1, l'application est concernée.
  • b. Chercher dans les dépendances du projet (si vous avez accès au code source). Avec Maven :
    mvn dependency:tree | grep log4j
    Avec Gradle :
    ./gradlew dependencies | grep log4j
    Ces commandes affichent aussi les dépendances indirectes - une bibliothèque tierce qui embarque elle-même Log4j sans que vous l'ayez choisi. C'est le cas le plus fréquent et le plus facile à manquer.
  • c. Ne pas s'arrêter à la première réponse négative. Un serveur peut ne pas exposer Log4j directement mais l'utiliser via un outil tiers installé dessus (un serveur d'applications, une passerelle de journalisation…). Si vous gérez un grand parc, un outil de recherche de composants (SCA) ou l'inventaire de vos logiciels vaut mieux qu'une recherche manuelle machine par machine.

Trois autres CVE, découvertes juste après la première, touchent la même bibliothèque et méritent d'être corrigées en même temps : CVE-2021-45046 (contournement partiel du premier correctif), CVE-2021-45105 (déni de service par boucle de lookup), et CVE-2021-44832 (une variante nécessitant un accès en écriture à la configuration). La version 2.17.1 corrige l'ensemble.

4. Étapes de correction, dans l'ordre

Étape 1 - Choisir la bonne version cible

  • Java 8 et plus récent : passez à la dernière version 2.x disponible, avec un minimum absolu de 2.17.1.
  • Java 7 : la dernière version compatible est 2.12.4.
  • Java 6 : la dernière version compatible est 2.3.2.

Vérifiez la version de Java de votre application avant de choisir : java -version.

Étape 2 - Mettre à jour la dépendance

Si le projet utilise Maven, ouvrez le fichier pom.xml et changez le numéro de version des dépendances log4j-core et log4j-api :

pom.xml

<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.17.1</version>
</dependency>

Puis reconstruisez le projet :

mvn clean package

Avec Gradle, dans build.gradle :

implementation 'org.apache.logging.log4j:log4j-core:2.17.1'

puis ./gradlew build.

Étape 3 - Si vous ne pouvez pas reconstruire l'application tout de suite

Cela arrive : logiciel commercial fermé, absence temporaire de l'équipe qui maintient le code, fenêtre de changement trop lointaine. Deux mesures de repli, à n'utiliser que provisoirement :

  • Retirer la classe fautive de l'archive existante, sans rien reconstruire :
    zip -q -d chemin/vers/log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
    Cette commande supprime uniquement le morceau de code qui sait faire des recherches JNDI. Le reste de la journalisation continue de fonctionner normalement.
  • Poser une variable d'environnement qui désactive les lookups dans les messages : LOG4J_FORMAT_MSG_NO_LOOKUPS=true (ou l'option de démarrage -Dlog4j2.formatMsgNoLookups=true). ⚠️ Cette variable ne protège pas contre toutes les variantes découvertes ensuite (notamment CVE-2021-45046) - ce n'est qu'un pansement en attendant la vraie mise à jour, jamais une solution définitive.

Étape 4 - Vérifier que la correction a pris

Ne vous fiez pas au numéro écrit dans un fichier de configuration : vérifiez ce qui est réellement chargé au démarrage.

# Repérer le vrai fichier utilisé par l'application en cours d'exécution
find / -name "log4j-core-*.jar" 2>/dev/null

Le nom de fichier doit maintenant afficher un numéro de version conforme à l'étape 1. Si vous avez utilisé le retrait de classe (étape 3), vérifiez son absence :

unzip -l chemin/vers/log4j-core-*.jar | grep JndiLookup

Cette dernière commande ne doit rien afficher. Si une ligne apparaît, la classe est toujours présente et la mesure de repli n'a pas été appliquée correctement.

5. Détecter une tentative ou une compromission passée

  • Dans les journaux, cherchez le motif révélateur. Les attaquants l'obscurcissent souvent (par exemple en insérant des lookups imbriqués pour casser la casse du mot « jndi »), donc une recherche trop littérale en rate une partie :
    grep -riE '\$\{.*jndi' /var/log/
  • Sur le réseau, le signe le plus fiable est un serveur applicatif qui initie des connexions LDAP ou RMI sortantes - un serveur web n'a normalement aucune raison de parler LDAP à l'extérieur. Bloquer ces sorties au pare-feu réduit le risque même sans avoir encore patché.
La vraie leçon de Log4Shell

Le jour de la divulgation, la question n'était pas « comment corriger » - le correctif existait déjà - mais «  ai-je du Log4j ? ». Trois à cinq ans plus tard, des études indépendantes trouvent encore autour de 12 % des applications Java tournant sur une version vulnérable : la bibliothèque était enfouie dans des dépendances de dépendances, dans des produits dont personne ne soupçonnait qu'ils contenaient du Java. Les organisations qui ont répondu vite étaient celles qui savaient ce qu'elles faisaient tourner.

Besoin d'y voir clair sur votre parc

Kenawek recherche les composants vulnérables enfouis dans vos applications et vos dépendances, priorise et accompagne la remédiation. Parlons-en.

Sources