GitHub commit spoofing – Quand n'importe qui peut être Linus

Vous avez confiance dans le nom qui est affiché à côté d’un commit GitHub ?
Bah vous pouvez arrêter tout de suite car le chercheur Shani Lavi a documenté il y a quelques années ce que les devs Git sérieux savent depuis longtemps : N’importe qui peut publier un commit avec n’importe quelle identité, et bien sûr, on peut systématiquement compter sur GitHub pour lier ce commit au profil correspondant sans broncher.
Allez, petite démonstration récente… Sur le repo
no-as-a-service
, il y a par exemple un commit signé "torvalds" qui ajoute un témoignage humoristique de Linus Torvalds dans le README. L’avatar de Linus s’affiche, et GitHub considère ça comme un commit parfaitement valide. Sauf que Linus n’a évidemment jamais touché ce projet humoristique qui est une petite API qui sort des excuses créatives pour dire "non".
Et ce qui est fou, c’est que vous pouvez faire pareil en dix secondes, et c’est ce qu’on va faire ensemble. Mais avant…
Pourquoi Git laisse passer ça
Git, à la base, c’est un système distribué. Quand vous faites un commit, votre client local prend alors deux infos dans votre config : user.name et user.email. Ces deux champs sont libres, et jamais validés côté client. Vous pouvez donc écrire ce que vous voulez dedans, et Git s’en fiche.
Côté GitHub, l’attribution se fait par l’email. Le service regarde alors l’email présent dans les métadonnées du commit, le compare aux emails enregistrés sur les comptes, et affiche le profil + l’avatar Gravatar correspondant. En fait, il n’y a aucune vérification que la personne qui a poussé le commit possède réellement cette adresse email.
Du coup, n’importe qui qui connaît votre email public (et il est public si vous avez déjà commit en clair sur un repo) peut publier des commits avec votre identité affichée.
Étape 1 : Reproduire le spoofing (à but pédagogique évidemment)
Avant de paniquer, faisons l’exercice nous-mêmes pour bien comprendre. Dans un repo de test que vous contrôlez :
# 1. Visualiser un commit cible pour récupérer name + email
git log --format='%an <%ae>' | head -3
# 2. Reconfigurer Git avec une fausse identité
git config --global --replace-all user.name "Linus Torvalds"
git config --global --replace-all user.email "torvalds@linux-foundation.org"
# 3. Vérifier la config
git config --global --list | grep user
# 4. Faire un commit normal
echo "Hello from Linus" >> README.md
git add README.md
git commit -m "Important kernel fix"
# 5. Pousser sur votre repo
git push origin main

Allez voir le commit sur GitHub. Vous verrez l’avatar de Linus, son nom cliquable qui mène vers son profil, et surtout aucun avertissement. Pas de mot de passe demandé ni de token compromis… non, non, non, c’est juste une config locale modifiée.
Et si quelqu’un fait un fork de votre repo, ou si un mainteneur peu attentif valide un PR sur cette base, l’illusion est complète.
Étape 2 : Repérer un commit douteux
Pour ça, le badge Verified reste l’indicateur le plus utile. À côté du SHA d’un commit, GitHub affiche surtout une étiquette verte "Verified" si le commit est cryptographiquement signé avec une clé GPG ou SSH enregistrée sur le compte de l’auteur. Sinon, y’a rien du tout (par défaut). Attention quand même, l’absence de badge ne veut pas dire qu’un commit est malveillant mais juste qu’on ne peut pas garantir qui l’a écrit.
Par exemple, si vous regardez le commit e6b4218 sur no-as-a-service, vous remarquerez l’absence totale de badge. C’est le signal mais il faut encore savoir le chercher car par défaut, GitHub n’affiche AUCUN avertissement pour les commits non signés. C’est surtout ça le problème…
Étape 3 : Signer vos commits avec SSH
Alors pour vous protéger de ça, ça commence chez vous. Plus simple que GPG, la signature SSH utilise une clé que vous avez probablement déjà. Générez une clé Ed25519 si ce n’est pas fait :
ssh-keygen -t ed25519 -C "votre@email.com"
Configurez Git pour signer automatiquement avec cette clé :
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true
Dernière étape, ajoutez votre clé publique sur GitHub dans Settings → SSH and GPG keys (1), mais cette fois en sélectionnant le type Signing Key (pas Authentication Key, c’est différent) (2). Vos prochains commits afficheront le badge "Verified" en vert.
Si vous préférez GPG, le principe est identique avec gpg.format gpg et une clé GPG. Pour le détail GPG complet, j’avais déjà couvert le sujet dans
le tuto sur Thunderbird et GPG
.
Étape 4 : Activer Vigilant Mode
Là, on passe à l’offensive. Vigilant Mode (3) force GitHub à afficher un statut sur tous vos commits. Les signés deviennent "Verified", les non signés deviennent "Unverified" en gros et bien visible. Plus de zone grise comme ça.

Direction même endroit dans Settings → SSH and GPG keys → Vigilant mode → Flag unsigned commits as unverified. Cochez la case. À partir de là, n’importe quel commit que GitHub vous attribue (via votre email vérifié) sans signature sera affiché comme "Unverified", ce qui rend le spoofing beaucoup plus difficile à dissimuler. Petite limite par contre, ça ne protège que votre propre identité et pas celle des contributeurs qui n’ont pas activé le mode.
La position de GitHub (et pourquoi je trouve ça discutable)
GitHub considère ce comportement comme un non-bug. Sur leur page bug bounty, l’usurpation par email Git est explicitement listée comme ineligible. Leur argument c’est que ça ne donne pas accès aux repos ni de privilèges supplémentaires, donc ce n’est pas une faille au sens strict.
Sauf que dans la vraie vie, l’identité affichée influence les décisions. Par exemple, un mainteneur qui voit un PR signé d’un contributeur connu va l’examiner avec moins de paranoïa, un journaliste qui couvre un scandale va citer "le commit de tel développeur" sans vérifier la signature, et combiné à d’autres vecteurs, ça peut devenir redoutable ! Je pense surtout aux
attaques supply chain récentes type Shai-Hulud
où une fois le code piégé, l’attribution Git aide à le faire passer pour légitime.
Bref, dire "ce n’est pas un bug" parce qu’il faut un autre vecteur derrière, c’est un peu facile, je trouve. Voilà, donc ne comptez pas sur Github pour vous défendre et signez vos commits, activez Vigilant Mode, et apprenez à vos collègues et amis dev à vérifier le badge "Verified" avant de merger quoi que ce soit en venant d’un inconnu… même si c’est ce bon cher Linus qui propose de réécrire le kernel en Rust avec systemd intégré ^^.
Source : korben.info