Passer au contenu principal

CVE-2026-3854 : exécution de code à distance via git push sur GitHub

Romain Grosos

Le 4 mars 2026, les chercheurs de Wiz ont signalé à GitHub une vulnérabilité critique permettant à tout utilisateur authentifié d'exécuter du code arbitraire sur les serveurs de la plateforme via une simple commande git push. Aucun outil spécial n'était nécessaire : un client git standard suffisait. La faille, référencée CVE-2026-3854 (CVSS 8.7), affecte à la fois GitHub.com et GitHub Enterprise Server.

Architecture interne du pipeline git

Quand un utilisateur exécute git push via SSH, la requête traverse plusieurs services internes :

  • babeld : proxy git, point d'entrée de toutes les opérations SSH. Il authentifie la connexion via gitauth et construit un header interne nommé X-Stat contenant les métadonnées de sécurité de la session.
  • gitauth : vérifie les droits de l'utilisateur et retourne les politiques applicables (limites de taille, règles de nommage de branches, etc.).
  • gitrpcd : serveur RPC interne. Il reçoit la requête de babeld, parse le header X-Stat et configure l'environnement pour les processus en aval. Il n'effectue aucune authentification propre : il fait entièrement confiance à babeld.
  • Le hook pre-receive : binaire Go compilé qui applique les politiques de sécurité avant d'accepter le push.

Le header X-Stat est le lien critique entre ces composants. Il transporte des champs de sécurité sous forme de paires clé=valeur délimitées par des points-virgules. Les services qui parsent ce header appliquent une sémantique last-write-wins : si une clé apparaît deux fois, la dernière valeur l'emporte silencieusement.

La vulnérabilité : injection de champs via les push options

Git supporte une fonctionnalité standard appelée push options : des chaînes arbitraires que le client peut envoyer au serveur lors d'un push (git push -o "valeur"). babeld encode ces valeurs dans le header X-Stat sous forme de champs numérotés (push_option_0, push_option_1...).

Le problème : babeld copie les valeurs des push options verbatim dans le header, sans filtrer les points-virgules. Or le point-virgule est le délimiteur de champs dans X-Stat. Une push option contenant ; suivi d'un nom de champ interne crée donc un nouveau champ contrôlé par l'attaquant. Grâce à la sémantique last-write-wins, ce champ injecté écrase le champ légitime.

Les chercheurs ont confirmé l'injection à la fois par analyse binaire (reverse engineering du composant compilé) et par capture réseau sur une instance GHES en production.

Parmi les champs injectables dans X-Stat, trois sont directement liés à l'exécution de code :

  • rails_env : contrôle le chemin d'exécution des hooks (mode sandbox ou exécution directe).
  • custom_hooks_dir : répertoire de base dans lequel le binaire pre-receive recherche les scripts hooks.
  • repo_pre_receive_hooks : définitions JSON des hooks pre-receive à exécuter.

Chaîne d'escalade vers l'exécution de code à distance

La compromission complète s'obtient en enchaînant trois injections :

  • Étape 1 - Sortie du sandbox. Injecter une valeur non-production dans rails_env bascule le binaire pre-receive du chemin d'exécution sandboxé vers un chemin non isolé, avec accès direct au système de fichiers.
  • Étape 2 - Redirection du répertoire hooks. Injecter custom_hooks_dir avec un chemin contrôlé par l'attaquant déplace la base de recherche des scripts.
  • Étape 3 - Path traversal vers un binaire arbitraire. Injecter repo_pre_receive_hooks avec une définition contenant une séquence de traversal (../) pour pointer vers n'importe quel binaire présent sur le système.

Le binaire pre-receive résout alors le chemin final et l'exécute directement, sans arguments, sans sandbox, en tant qu'utilisateur de service git.

git push -o 'legit_value;rails_env=test;custom_hooks_dir=/tmp/a;repo_pre_receive_hooks=[{"script":"../../bin/sh"}]' origin main

remote: uid=500(git) gid=500(git) groups=500(git)

GitHub.com : une injection supplémentaire

Sur GitHub.com, les custom hooks ne sont pas actifs par défaut. Un flag interne (enterprise_mode) dans le header X-Stat contrôle cette activation. Ce flag étant lui aussi transmis via le header, il était injectable par le même mécanisme. Une injection supplémentaire activait le mode enterprise, rendant l'exploit pleinement fonctionnel sur GitHub.com.

Impact confirmé

L'utilisateur git existe pour une raison : il gère toutes les opérations sur les dépôts du nœud. Par conception, il dispose d'un accès étendu en lecture/écriture à chaque dépôt hébergé sur ce nœud, quelle que soit l'organisation propriétaire.

Sur GitHub.com, les chercheurs ont listé les entrées d'index de deux nœuds compromis et y ont trouvé des millions de dépôts appartenant à d'autres utilisateurs et organisations (publics et privés). Sur GHES, la compromission est totale : système de fichiers, secrets de configuration interne, tous les dépôts hébergés.

GitHub a conduit une investigation forensique après le signalement. Les logs ont confirmé que le code path anormal (celui déclenché par l'injection) n'avait été activé que par les chercheurs Wiz dans le cadre de leurs tests. Aucune exploitation préalable n'a été détectée, aucune donnée client accédée ou exfiltrée.

Réponse de GitHub

Le signalement a été reçu le 4 mars 2026 à 17h45 UTC. En moins de 40 minutes, l'équipe sécurité de GitHub avait reproduit la vulnérabilité et confirmé sa criticité. Le correctif a été déployé sur GitHub.com à 19h00 UTC le même jour, soit moins de deux heures après la réception du rapport.

Le correctif primaire consiste à sanitiser les valeurs des push options avant leur intégration dans le header X-Stat. Une mesure de défense en profondeur a également été appliquée : le code path lié au mode enterprise a été supprimé des environnements où il ne devait pas être présent. Cette seconde mesure limite l'exploitabilité de vulnérabilités similaires à l'avenir, même en cas d'injection réussie.

La faille a reçu l'un des montants de bug bounty les plus élevés de l'histoire du programme GitHub.

GHES : versions corrigées et détection

Au 28 avril 2026, date de publication du rapport de Wiz, 88 % des instances GitHub Enterprise Server étaient encore vulnérables. Toutes les versions jusqu'à 3.19.1 incluse sont affectées.

Les versions minimales intégrant le correctif sont :

  • 3.14.25 (et suivantes dans la branche 3.14)
  • 3.15.20
  • 3.16.16
  • 3.17.13
  • 3.18.7
  • 3.19.4
  • 3.20.0

Pour détecter une tentative d'exploitation sur une instance non encore mise à jour, GitHub recommande de rechercher la présence de points-virgules dans les push options des logs d'audit :

grep ";" /var/log/github-audit.log | grep push

La mise à jour reste l'unique remédiation fiable. L'exploitation ne requiert qu'un accès authentifié avec droits push sur un seul dépôt, y compris un dépôt créé par l'attaquant lui-même.

Le rôle de l'IA dans la découverte

Wiz souligne dans son rapport que cette vulnérabilité est l'une des premières CVE critiques découvertes via du reverse engineering IA-assisté. L'équipe a utilisé IDA MCP, un outil d'analyse de binaires compilés augmenté par IA, pour analyser les composants closed-source du pipeline git de GitHub : reconstruction du protocole interne, cartographie des flux de données utilisateur, identification systématique des points d'injection potentiels.

Cette approche a rendu abordable une tâche qui aurait nécessité un investissement manuel considérable. C'est un signal fort pour la communauté sécurité : les binaires fermés ne bénéficient plus du même niveau de protection par l'obscurité. La surface d'analyse accessible aux chercheurs (et aux attaquants) s'est significativement élargie.

Sources

GitHub RCE Vulnerability: CVE-2026-3854 Breakdown | Wiz Blog
A CVSS 8.7 vulnerability in GitHub Enterprise Server allows remote code execution. Read the threat brief and find vulnerable GHES instances from Wiz.
Securing the git push pipeline: Responding to a critical remote code execution vulnerability
How we validated, fixed, and investigated a critical vulnerability in under two hours, and confirmed no exploitation.
Cette faille GitHub est exploitable par un simple Git Push (CVE-2026-3854)
Une simple commande git push pour compromettre un serveur ? C’est possible grâce à la faille CVE-2026-3854 qui affecte GitHub.com et GitHub Enterprise Server.
CVE-2026-3854 Exposes a Critical Weak Point in GitHub’s Git Push Pipeline
CVE-2026-3854 is a critical remote code execution vulnerability tied to how GitHub handled user-supplied git push options during the push pipeline…