Aller au contenu
medium

actions-cool/issues-helper : 53 tags pointent sur un commit piégé

10 min de lecture

Le 18 mai 2026, 53 tags de l'action GitHub actions-cool/issues-helper ont été réécrits en moins de 3 minutes 16 secondes pour pointer vers un commit imposteur qui exfiltre les secrets CI/CD depuis la mémoire du process Runner.Worker. Une seconde action de la même organisation, actions-cool/maintain-one-comment, a subi le même traitement dans la même fenêtre (15 tags en 39 secondes). Seuls les workflows épinglés par SHA de commit légitime complet sont épargnés. Cet article décrit le mécanisme, les IOCs publiés par StepSecurity, et l'action immédiate à mener si vous utilisez l'une de ces actions.

Ce que vous allez apprendre

  • Comprendre ce qu'est un commit imposteur dans une attaque par tag poisoning
  • Identifier si vos workflows utilisent l'une des actions compromises
  • Détecter les indicateurs de compromission côté runner
  • Vous protéger par épinglage SHA et bloquer la sortie réseau du payload
  • Renforcer votre posture après l'incident

Dans quel contexte ?

Cette attaque concerne tout dépôt qui consomme actions-cool/issues-helper ou actions-cool/maintain-one-comment via un tag — typiquement @v3, @v3.7.6, @v2. C'est le pattern par défaut quand on copie un exemple de la Marketplace GitHub Actions : facile à écrire, fragile en réalité. La règle de défense — épingler chaque action par le SHA complet du commit — n'est plus une recommandation d'expert depuis le précédent de tj-actions/changed-files en mars 2025. Mais elle reste encore massivement ignorée, et chaque nouvelle compromission rappelle pourquoi.

Ce qui s'est passé

L'attaquant a obtenu la capacité de déplacer les tags dans le dépôt GitHub actions-cool/issues-helper. Il a généré un commit imposteur par tag — chacun avec un message de commit factice du style "Build action for vX.Y.Z" qui imite la convention du mainteneur — et re-pointé l'ensemble des 53 tags sur ces nouveaux commits, qui ne sont rattachés à aucune branche du dépôt (commits orphelins).

Le tell est dans le timing : les 53 commits imposteurs ont tous été créés entre 19:10:24 et 19:13:40 UTC le 2026-05-18. La même opération a été menée 17 minutes plus tard sur maintain-one-comment, avec 15 commits créés en 39 secondes. Un humain ne tape pas 53 commits artisanaux en 3 minutes — c'est de l'automatisation.

Côté payload, quand un workflow exécute l'action compromise sur un runner :

  1. Téléchargement du runtime JavaScript bun dans /home/runner/.bun/bin/bun.
  2. Lecture de /proc/<Runner.Worker PID>/mem depuis un process Python enfant. C'est ce process Runner.Worker qui détient les secrets déchiffrés du workflow.
  3. Filtrage de la mémoire à la recherche de "isSecret":true, puis extraction des tokens d'authentification (gh auth token, secrets de pipeline).
  4. Exfiltration HTTPS vers t.m-kosche.com sur le port 443.

Sources : l'analyse complète et les IOCs sont publiés par StepSecurity. Les mainteneurs ont été notifiés via l'issue #11 du dépôt.

Êtes-vous concerné ?

Lancez cette commande à la racine de chaque dépôt :

Fenêtre de terminal
grep -rE "actions-cool/(issues-helper|maintain-one-comment)" \
.github/workflows/ 2>/dev/null

Trois cas de figure :

  • Aucun résultat : vous n'utilisez pas ces actions. Lisez la suite pour les bons réflexes en prévention.
  • Référence par tag (@v3, @v3.7.6, @v2, etc.) : votre workflow est compromis dès le prochain run. Action immédiate ci-dessous.
  • Référence par SHA : vérifiez que le SHA ne fait pas partie des commits imposteurs. Tous les SHA dans la liste publiée par StepSecurity sont à proscrire. Si votre SHA n'y figure pas, il est probablement légitime — confirmez en vérifiant qu'il appartient à la branche par défaut du dépôt.

Action immédiate

Une fois la rotation faite, deux options pour la suite :

  1. Supprimer l'usage de l'action si elle n'est pas critique. C'est l'option la plus sûre tant que les mainteneurs n'ont pas repris le contrôle du dépôt et publié une déclaration officielle.

  2. Épingler sur le dernier SHA légitime — celui de la branche master à la veille de l'incident. Concrètement :

    # AVANT — vulnérable
    - uses: actions-cool/issues-helper@v3
    # APRÈS — SHA d'un commit légitime de la branche master
    - uses: actions-cool/issues-helper@<SHA-de-master-pré-18-mai-2026> # v3

    Pour récupérer un SHA légitime, ouvrez l'historique de la branche master du dépôt sur GitHub à une date antérieure au 18 mai. Ne prenez pas un SHA depuis un tag — tous ont été détournés.

Si vous utilisez l'outil StepSecurity Harden-Runner avec egress block mode, l'exfiltration vers t.m-kosche.com est déjà bloquée. Cela n'empêche pas la lecture de mémoire mais bloque la fuite des secrets — défense en profondeur.

Auditer son parc en une commande avec Plumber

Vérifier à la main que chaque uses: de chaque workflow est épinglé par SHA ne tient pas la route au-delà d'une poignée de dépôts. C'est exactement ce que fait Plumber — scanner de conformité CI/CD qui couvre GitHub Actions et GitLab CI. Son contrôle ISSUE-104 flagge toute action référencée par tag ou par SHA non épinglé, soit précisément la surface d'attaque du tag poisoning :

Fenêtre de terminal
# À la racine d'un dépôt GitHub
plumber analyze --score

Sortie type sur un workflow vulnérable :

CRIT [ISSUE-104] Third-party actions must be pinned by commit SHA
.github/workflows/issues.yml:12
actions-cool/issues-helper@v3 — référence mutable (tag)

Bonus : Plumber maintient aussi une base de SHA d'actions porteuses de CVE (contrôle ISSUE-703). Dès que les SHA imposteurs publiés par StepSecurity remontent dans cette base, un workflow qui aurait épinglé par erreur sur l'un d'eux serait également alerté. Lancez plumber analyze dans une étape CI pour bloquer toute pull request qui régresse sur ces contrôles — c'est exactement ce qui aurait empêché l'incident chez les consommateurs disciplinés.

Indicateurs de compromission

Sur un runner compromis, vous trouverez :

  • Présence du binaire bun dans /home/runner/.bun/bin/bun alors qu'il n'est pas attendu par votre workflow.
  • Lectures de /proc/<PID>/mem depuis un process python3 enfant, avec des pipelines tr/grep qui filtrent sur "isSecret":true.
  • Connexion HTTPS sortante vers le domaine t.m-kosche.com sur le port 443.

Ce domaine est désormais sur la liste de blocage globale de Harden-Runner. Si vous gérez votre propre liste d'allow-list réseau pour les runners, vous pouvez l'ajouter à vos règles de firewall sortant.

Pourquoi cette attaque répète le même pattern

C'est la troisième fois en deux mois qu'on observe le même mode opératoire : un attaquant prend le contrôle d'un dépôt GitHub Actions, réécrit tous les tags pour qu'ils pointent vers du code malveillant qui vole les secrets via la mémoire de Runner.Worker. Avant actions-cool/, il y a eu Trivy (deux fois) et KICS de Checkmarx. Ce n'est plus un incident isolé, c'est un playbook industrialisé.

La cible est toujours la même : les actions populaires qui s'exécutent avec les secrets de production et que les équipes consomment par tag, pas par SHA. La défense aussi est la même — et elle n'est pas négociable :

GitHub lui-même reconnaît le problème : la roadmap sécurité GitHub Actions 2026 annonce un système de lock files de dépendances (équivalent go.mod/go.sum pour les workflows) qui figera tous les SHAs directs et transitifs. Public preview annoncée à 3-6 mois — en attendant, la discipline manuelle reste la seule défense.

À retenir

  • Tag poisoning : un attaquant qui contrôle un dépôt peut réécrire l'ensemble des tags pour pointer vers du code malveillant. Les utilisateurs pinned par tag récupèrent le payload à leur prochain run.
  • Mémoire du Runner.Worker : c'est le process qui détient les secrets déchiffrés. Lire /proc/<PID>/mem suffit à les extraire — pas besoin de contourner GitHub Secrets.
  • L'épinglage par SHA légitime est la seule défense fiable et gratuite. Tout le reste (rotation, monitoring, allow-list) est un complément.
  • Le pattern se répète : Trivy en mars, KICS en avril, actions-cool en mai. Chaque mois, une nouvelle action populaire. Considérez que les actions tierces de votre .github/workflows/ doivent être épinglées avant la prochaine vague — pas après.
  • Le lock file de workflow arrive côté GitHub natif courant 2026 : préparez vos workflows en pinned-SHA dès maintenant, vous gagnerez du temps à la migration.

Prochaines étapes

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn