❌ Tag (@v4)
- C’est une étiquette mobile
- Peut pointer vers n’importe quel code
- Modifiable par le mainteneur (ou un attaquant)
Mise à jour :
Vous utilisez probablement des actions GitHub comme actions/checkout@v4 dans
vos workflows. Ce @v4 semble anodin, mais c’est une faille de sécurité
qui a déjà permis des attaques réelles. Ce guide vous explique pourquoi et
comment vous protéger.
@v4 ?Imaginez que vous commandez toujours “le plat du jour” au restaurant. Hier, c’était un délicieux poulet rôti. Mais demain, sans vous prévenir, le chef pourrait le remplacer par quelque chose de toxique. Vous faites confiance au nom “plat du jour”, pas au contenu réel.
C’est exactement ce qui se passe avec @v4 : vous faites confiance au nom
du tag, mais son contenu peut changer à tout moment.
Un tag Git comme @v4 est simplement une étiquette qu’on colle sur un
commit. Le problème ? Cette étiquette est mobile : n’importe qui ayant
accès au dépôt peut la déplacer vers un autre commit.
❌ Tag (@v4)
✅ SHA (empreinte)
Ce n’est pas de la science-fiction. En mars 2025, l’action populaire tj-actions/changed-files a été compromise exactement de cette façon.
Jour 1 : Vous utilisez action/exemple@v4 qui pointe vers le commit
abc123 — du code légitime, testé et validé.
Jour 30 : Un attaquant compromet le compte du mainteneur (phishing, mot de passe faible, token volé…).
L’attaquant déplace le tag : @v4 pointe maintenant vers un nouveau
commit xyz789 contenant du code malveillant.
Jour 31 : Votre workflow se lance. Il récupère @v4… et exécute le
code malveillant sans que vous ne remarquiez rien !
Résultat : Vos secrets (GITHUB_TOKEN, clés API, credentials) sont
exfiltrés vers l’attaquant.
Au lieu de faire confiance à une étiquette mobile, utilisez l’empreinte cryptographique (SHA) du commit. C’est comme donner l’empreinte digitale exacte du code que vous voulez exécuter.
# ❌ Dangereux : tag mutable — peut changer à tout moment- uses: actions/checkout@v4
# ✅ Sécurisé : SHA immuable — toujours le même code- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2Pourquoi le commentaire # v4.2.2 ? Il indique à quelle version
correspond ce SHA. C’est purement informatif pour vous (et Dependabot), mais
c’est le SHA qui compte pour la sécurité.
Vous avez compris pourquoi utiliser un SHA. Maintenant, comment le trouver ? Plusieurs méthodes existent, de la plus simple à la plus automatisée.
# Obtenir le SHA du tag v4.2.2 de l'action checkoutcurl -s https://api.github.com/repos/actions/checkout/commits/v4.2.2 \ | jq -r .shaRésultat attendu : 11bd71901bbe5b1630ceea73d27597364c9af683
gh api repos/actions/checkout/commits/v4.2.2 --jq .shagithub.com/actions/checkout)Convertir manuellement chaque action serait fastidieux et source d’erreurs. Heureusement, des outils font le travail pour vous.
Cet outil analyse vos workflows et remplace automatiquement les tags par leurs SHA :
# Installer l'outilnpm install -g pin-github-action
# Convertir un seul workflowpin-github-action .github/workflows/ci.yml
# Convertir TOUS les workflows d'un coupfind .github/workflows -name "*.yml" -exec pin-github-action {} \;Avant (vulnérable) :
- uses: actions/checkout@v4- uses: actions/setup-node@v4Après (sécurisé) :
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0Si vous préférez une interface graphique, app.stepsecurity.io ↗ offre une solution simple :
Bonus : StepSecurity analyse aussi d’autres aspects de sécurité de vos workflows (permissions, secrets exposés, etc.).
Un SHA épinglé, c’est bien. Mais les actions reçoivent des mises à jour de sécurité et des nouvelles fonctionnalités. Comment rester à jour sans revenir aux tags mutables ?
Dependabot surveille vos dépendances et crée automatiquement des Pull Requests quand de nouvelles versions sont disponibles :
version: 2updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" # Vérifie chaque semaine commit-message: prefix: "ci" # Préfixe des commits : "ci: ..."Comment ça marche : Dependabot
détecte le commentaire # v4.2.2 dans vos workflows. Quand v4.2.3 sort, il
crée une PR qui met à jour le SHA et le commentaire. Vous n’avez qu’à review
et merger !
Renovate est une alternative à Dependabot avec plus d’options de configuration :
{ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["config:base"], "github-actions": { "enabled": true, "pinDigests": true }}Comment savoir si vos workflows sont correctement sécurisés ? L’outil Scorecard de l’OpenSSF analyse votre dépôt et note vos pratiques de sécurité :
scorecard --local . --checks Pinned-Dependencies --show-detailsInterprétation du score :
| Score | Signification |
|---|---|
| 10/10 | Parfait ! Toutes les actions sont épinglées par SHA |
| 5-9/10 | Certaines actions utilisent encore des tags |
| 0/10 | Danger ! Tags mutables partout (@v1, @latest, @main) |
Oui ! Même si les actions maintenues par GitHub (actions/*) sont plus
fiables que les actions tierces, l’épinglage reste une bonne pratique :
| Action | Usage | Pourquoi l’épingler |
|---|---|---|
actions/checkout | Cloner le repo | A accès à votre code source |
actions/setup-node | Installer Node.js | Exécute des scripts sur le runner |
actions/setup-python | Installer Python | Idem |
actions/cache | Cache des dépendances | Manipule des fichiers |
actions/upload-artifact | Sauvegarder des artifacts | A accès aux fichiers produits |
actions/download-artifact | Récupérer des artifacts | Peut injecter des fichiers |
Le principe : tout code qui s’exécute dans votre CI mérite d’être vérifié et épinglé, quelle que soit sa source.
Toutes les actions ne se valent pas. Avant d’ajouter une action tierce à vos workflows, posez-vous ces questions :
✅ Signaux positifs
⚠️ Signaux d'alerte
permissions: write-allVoici un workflow qui applique toutes les bonnes pratiques :
name: CI
# Permissions minimales par défautpermissions: contents: read
on: push: branches: [main] pull_request:
jobs: build: runs-on: ubuntu-latest steps: # Toutes les actions sont épinglées par SHA - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 20 cache: npm
- run: npm ci - run: npm test
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: coverage path: coverage/Ce qui rend ce workflow sécurisé :
permissions: contents: read — droits minimauxConvertir tous vos workflows avec pin-github-action ou StepSecurity
Configurer Dependabot pour garder les SHA à jour automatiquement
Vérifier régulièrement avec Scorecard que rien n’a été oublié