Je suis habitué aux compromissions de paquets. Un mainteneur se fait voler ses accès, une version malveillante part sur npm ou PyPI, et tous ceux qui l'installent exécutent le code de l'attaquant. Le schéma est rodé, on sait quoi chercher.
L'analyse publiée par Socket le 22 juillet 2026 décrit autre chose, et c'est ce qui m'a fait tiquer. Installer le paquet compromis n'exécute rien du tout. Le code de la librairie est propre. Ce qui est vérolé, ce sont les fichiers de workflow GitHub Actions à la racine des dépôts. Et la charge utile ne vise pas les utilisateurs du paquet : elle transforme les dépôts eux-mêmes en scanner Internet distribué, chargé d'exploiter une faille critique de cPanel et WHM.
Autrement dit, le dépôt n'est pas le vecteur de contamination. Il est l'infrastructure de calcul de l'attaquant. Et il l'utilise gratuitement, sur des runners GitHub.
Ce qui s'est passé
L'enquête part de Packagist, le dépôt de paquets PHP. Dix paquets appartenant à un développeur PHP et DevOps légitime, dinushchathurya, ont exposé des versions de développement malveillantes. Ce développeur est une victime, pas l'attaquant : ses dépôts GitHub ont été compromis, et Packagist a fait son travail en synchronisant automatiquement, les 12 et 13 juillet 2026, ce que l'attaquant y avait poussé.
Chaque version affectée embarquait entre 55 et 62 fichiers de workflow malveillants, soit 583 fichiers au total sur les dix paquets. Ce ne sont pas des versions stables publiées, mais des versions de branche, ce qui explique qu'elles soient passées sous le radar d'une bonne partie des consommateurs.
Le point que je trouve le plus instructif tient en une phrase de l'analyse : le code PHP est bénin. Données statiques, fonctions de recherche ordinaires, aucun hook d'installation, aucune activité réseau. Toute l'attaque vit dans .github/workflows/.
Pourquoi installer le paquet ne déclenche rien
C'est le détail qui renverse les réflexes habituels, et il mérite qu'on s'y arrête.
Quand vous installez le paquet via Composer, Packagist le place dans le répertoire vendor/ de votre projet. Or GitHub ignore les fichiers de workflow imbriqués : seuls ceux situés dans .github/workflows à la racine du dépôt sont pris en compte. Les workflows malveillants se retrouvent donc inertes chez le consommateur. Cloner le dépôt sur son poste n'exécute rien non plus.
L'exécution se produit dans un seul cas : quand le dépôt compromis lui-même reçoit un push, ou quand quelqu'un lance manuellement le workflow. Les workflows sont déclarés pour se réveiller sur n'importe quelle branche, avec un délai d'exécution très généreux :
on: push: branches: ['**'] workflow_dispatch:jobs: run: runs-on: ubuntu-latest timeout-minutes: 350Ces 350 minutes ne sont pas là par hasard. Un scanner Internet a besoin de temps, et l'attaquant se sert du quota du dépôt compromis.
Le runner comme machine à scanner
Le déroulé sur le runner est méthodique. Le workflow détecte d'abord l'architecture du processeur, puis télécharge la charge utile correspondante depuis un serveur de commande et contrôle joignable par adresse IP brute, sans nom de domaine.
Vient ensuite l'exécution en mode scanner :
/tmp/.svc ipscan \ --source random,all \ --exploit CVE-2026-41940 \ --git \ --envdump \ --ports 80,443,8080,8443,2082,2083,2086,2087Les ports listés sont la signature de la cible : 2082, 2083, 2086 et 2087 sont les ports historiques de cPanel et WHM. Les drapeaux --git et --envdump annoncent la couleur, on cherche des dépôts et des variables d'environnement.
Le tout est piloté comme un vrai outil d'exploitation. Un battement de cœur toutes les 30 secondes remonte l'état d'avancement et la dernière ligne de log, en identifiant le dépôt d'où part le scan. Les résultats sont exfiltrés par POST HTTP, découpés en morceaux, avec un suivi des décalages de lignes pour ne jamais renvoyer deux fois la même donnée. L'étape finale d'exfiltration s'exécute même si le scanner a échoué.
Ce que le scanner récolte sur les serveurs atteints donne le vertige : identifiants AWS, jetons GitHub et GitLab, clés d'API OpenAI et Google, clés Stripe, identifiants SendGrid et Mailgun, informations de bases de données, matériel SSH, dépôts distants Git, et résultats d'exécution de code à distance.
La faille visée, et pourquoi elle fait mal
La cible technique est CVE-2026-41940, un contournement d'authentification dans le flux de connexion de cPanel et WHM, présent sur les versions postérieures à la 11.40. Les chiffres parlent d'eux-mêmes.
| Indicateur | Valeur |
|---|---|
| Score CVSS | 9,8 (critique) |
| Vecteur | Réseau, sans authentification ni interaction |
| EPSS | 98,1 % de probabilité d'exploitation à 30 jours |
| Catalogue CISA KEV | Oui, exploitation avérée |
Un EPSS à 98,1 % conjugué à une présence dans le catalogue des vulnérabilités activement exploitées de la CISA, cela signifie que l'exploitation n'est pas une hypothèse théorique. Elle est en cours, à grande échelle.
La hiérarchie entre les deux produits explique l'intérêt de l'attaquant. cPanel administre le compte d'un client d'hébergement, avec ses sites, ses bases et ses courriels. WHM est le plan de contrôle au-dessus, qui crée et gère plusieurs comptes cPanel. Compromettre un WHM, c'est donc potentiellement ouvrir plusieurs environnements hébergés d'un coup.
Quelle ampleur, réellement
C'est le point sur lequel je veux être précis, parce que c'est là qu'on lit beaucoup d'approximations.
Une recherche de code sur GitHub, à partir d'un identifiant unique laissé par la campagne, remonte environ 6 100 fichiers de workflow correspondants. En élargissant aux autres marqueurs (adresse du serveur de commande, arguments du scanner, noms de fichiers de credentials, points d'exfiltration), on monte à 15 000 à 16 000 fichiers.
Ce que ces chiffres établissent en revanche, c'est que la campagne dépasse très largement le cas du mainteneur PHP initial. Du code identique et très distinctif se retrouve dans des dépôts sans aucun lien entre eux, dont des projets établis avec un historique de développement normal. Le compte du développeur victime a été suspendu, ce qui a coupé une voie de lancement, mais l'opération doit être considérée comme toujours active.
Ce que j'en retiens pour nos pipelines
Ce cas confirme une chose que je répète depuis les compromissions de Trivy et de Checkmarx KICS : un workflow CI est du code exécutable, pas de la configuration. Il mérite la même revue, les mêmes contrôles d'accès et la même surveillance que le code applicatif. Tant qu'on traitera le YAML de pipeline comme un détail d'intendance, ce genre de campagne prospérera.
Trois angles morts me semblent particulièrement exposés ici.
La revue des workflows. Sur beaucoup de projets, une modification sous .github/workflows passe avec la même légèreté qu'un changement de README. C'est exactement ce que l'attaquant exploite : il pousse 59 fichiers d'un coup, et personne ne regarde.
La sortie réseau des runners. Un runner qui télécharge un binaire depuis une adresse IP brute, puis qui envoie des POST toutes les 30 secondes vers cette même IP, c'est un comportement aberrant qu'aucun build légitime ne produit. Encore faut-il regarder.
Les versions de développement. Verrouiller ses dépendances sur des références de commit connues plutôt que sur des branches mouvantes aurait évité la synchronisation automatique des versions vérolées.
Ce que je ferais dès maintenant
Voici ce que j'appliquerais, dans cet ordre.
Sur vos dépôts, exigez une revue obligatoire de tout changement touchant .github/workflows, et vérifiez qu'aucun workflow inconnu ne s'y est glissé. Passez en revue les accès OAuth et applications GitHub, et faites tourner vos identifiants si un doute subsiste. Conservez les journaux d'exécution des Actions, ils sont votre seule trace si l'incident vous concerne.
Sur votre organisation, réduisez les permissions du GITHUB_TOKEN au strict nécessaire, ce que je détaille dans le guide sur les permissions des workflows. Surveillez la sortie réseau de vos runners et alertez sur tout téléchargement depuis une adresse IP brute : c'est précisément le rôle d'un outil comme Harden Runner. Épinglez vos actions par SHA de commit plutôt que par tag.
Sur vos dépendances PHP, bannissez les versions de développement non revues, vérifiez les références de commit de vos fichiers de verrouillage, et repassez sur des versions stables.
Et si vous exploitez du cPanel ou du WHM exposé sur Internet, appliquez le correctif de CVE-2026-41940 sans attendre, puis lancez le script de détection d'indicateurs de compromission fourni par cPanel sur toute machine restée exposée pendant la fenêtre.
À retenir
- Le code du paquet PHP est propre : l'attaque vit dans les fichiers de workflow du dépôt, pas dans la librairie.
- Installer le paquet n'exécute rien. Seul un push sur le dépôt compromis déclenche la charge utile.
- Les dépôts compromis servent d'infrastructure de scan distribuée, sur des runners GitHub, aux frais de la victime.
- La cible finale est CVE-2026-41940, contournement d'authentification cPanel et WHM, CVSS 9,8, EPSS 98,1 %, présent dans le catalogue CISA KEV.
- Les 6 100 à 16 000 fichiers repérés sont des fichiers correspondants, pas des dépôts compromis confirmés.
- Un workflow CI est du code exécutable et doit être revu, restreint et surveillé comme tel.
Liens utiles
- GitHub Actions : 15 pièges de sécurité qui exposent vos pipelines
- Checkmarx/KICS compromis : quand les scanners deviennent la surface d'attaque
- Shai-Hulud revient : un ver npm pille l'écosystème AntV
- Sécuriser GitHub Actions
- OWASP Top 10 CI/CD
- Plumber, scanner de pipelines CI/CD
Sources
- Socket, Large-Scale GitHub Actions Abuse Powers a Distributed cPanel and WHM Exploitation Campaign, 22 juillet 2026.
- NVD, CVE-2026-41940.
- GitHub, What's coming to our GitHub Actions 2026 security roadmap.