Ancaman serangan rantai pasok CodeQL – insiden keamanan yang bermula dari secret key GitHub yang terekspos publik
(praetorian.com)- Jika GITHUB_TOKEN yang terekspos publik sempat dimanfaatkan dalam masa berlakunya yang singkat, jalur serangan rantai pasok dapat terbuka dan berujung pada eksekusi kode di workflow GitHub Actions pada berbagai repositori yang menggunakan CodeQL
- Token tersebut berada di workflow artifact yang diunggah oleh workflow debug yang gagal di repositori
github/codeql-action, dan merupakan token instalasi GitHub App dengan izincontents: write,actions: write,packages: write - Keberhasilan serangan bergantung pada race condition untuk mengunduh dan menggunakan token dalam rentang setelah artifact diunggah hingga sebelum job selesai; berdasarkan log nyata sekitar 1,022 detik, dan dalam observasi sekitar 2 detik cukup untuk berhasil membuat branch, melakukan push
poc.txt, dan membuat tag - Karena konfigurasi default CodeQL secara internal menjalankan tag v3 dari
github/codeql-action, dan tag tersebut tidak immutable, jika penyerang memindahkan tag ke commit berbahaya, repositori yang menggunakan workflow CodeQL default pun dapat terdampak - Sekitar 3 jam setelah laporan, GitHub mengajukan PR untuk menonaktifkan unggahan debug artifact, menetapkan CVE-2025-24362, dan dalam advisory menyatakan tidak ada bukti kompromi terhadap platform atau sistem
Jalur serangan rantai pasok CodeQL yang bermula dari artifact publik
- Satu secret yang terekspos publik berpotensi mengarah pada serangan rantai pasok terhadap GitHub CodeQL
- Secret tersebut hanya valid sekitar 1,022 detik setiap kali, tetapi dalam rentang itu penyerang dapat melakukan langkah-langkah untuk mengeksekusi kode di dalam workflow GitHub Actions
- Cakupan dampaknya dapat menjangkau GitHub Cloud maupun GitHub Enterprise
- Potensi kerugiannya mencakup:
- kebocoran source code dari repositori private yang menggunakan CodeQL
- pencurian GitHub Actions secrets di dalam job workflow CodeQL
- eksekusi kode pada infrastruktur internal tempat workflow CodeQL berjalan
- pencurian secrets dari workflow yang menggunakan GitHub Actions Cache di repositori yang memakai CodeQL
- Berdasarkan advisory GitHub, GitHub tidak menemukan bukti kompromi terhadap platform atau sistem
Cara secret ditemukan
- Digunakan Actions Artifacts Secret Scanner, yang mengunduh artifact workflow GitHub Actions, mengekstrak arsipnya secara rekursif, lalu memindai secret dengan Nosey Parker
- Fitur ini diintegrasikan ke Chariot dan di-open-source-kan sebagai fitur Gato
- Setelah pemindaian selama satu hari, sebuah token ditemukan di artifact repositori
github/codeql-action- Artifact yang dimaksud adalah zip
my-debug-artifactsyang diunggah oleh workflow “PR Check – Debug artifacts after failure” - Setelah
my-db-java-partial.zipdi dalamnya diekstrak, GitHub Token yang diawalighs_terdeteksi di crash report - Pemeriksaan manual menunjukkan bahwa itu adalah token instalasi GitHub App yang tersimpan di dalam file berisi environment variable dari GitHub Runner
- Artifact yang dimaksud adalah zip
Struktur keterkaitan GitHub Actions, artifact, dan CodeQL
- GitHub Actions adalah platform CI/CD yang menjalankan tugas yang didefinisikan dalam workflow YAML pada runner
- Setiap workflow run otomatis membuat GITHUB_TOKEN, yaitu token instalasi GitHub App yang dibuat otomatis
- Runner menggunakan token ini untuk melakukan autentikasi ke GitHub dan menjalankan pekerjaan yang dibutuhkan workflow
- Izin dapat dikonfigurasi pada level file workflow, repositori, dan organisasi
- Artifact workflow GitHub Actions adalah file yang disimpan workflow di GitHub Actions untuk digunakan kemudian
- Secara default dapat diakses oleh orang yang memiliki izin baca ke repositori
- Disimpan hingga 90 hari
- CodeQL adalah mesin analisis kode milik GitHub, digunakan untuk melakukan analisis statis pada repositori GitHub dan menemukan kerentanan
- Tool keamanan seperti CodeQL terkadang harus mengakses sistem dan data sensitif, sehingga jika dikompromikan dapat menjadi backdoor
Izin token dan race condition
- Pada tahap “Setup Job” di log workflow, GITHUB_TOKEN tersebut terkonfirmasi memiliki izin tulis penuh
- Izin yang sangat penting antara lain:
contents: write: dapat membuat branch, membuat tag, dan mengunggah release artifactactions: write: dapat memicu pekerjaan Actions dan eventworkflow_dispatchpackages: write: dapat mengunggah package
- Karena token hanya valid selama workflow job tersebut berjalan, serangan membutuhkan tiga kondisi:
- token harus memiliki izin write
- harus menggunakan upload artifact API v4 yang dapat mengambil artifact sebelum job selesai
- waktu antara unggahan artifact dan selesainya job harus cukup untuk mengunduh token, mengekstrak arsip, dan menggunakannya
- CodeQL tidak memakai action
actions/upload-artifactsecara langsung, tetapi menggunakan upload artifact client secara manual dari source code, dan menurut komentar kode memakai version 4 - Berdasarkan raw log GitHub, jeda waktunya sangat singkat:
- “Finalizing artifact upload”: 17:22:09.888
- “Cleaning up orphan processes”: 17:22:10.911
- Secara perhitungan sekitar 1,022 detik, dan berdasarkan observasi token masih valid sekitar 1 detik lagi setelah cleanup, sehingga dianggap sekitar 2 detik
PoC: menjalankan artifact_racer.py
- Sebuah skrip Python untuk verifikasi,
artifact_racer.py, dibuat - Alur kerjanya sebagai berikut:
- terus melakukan query apakah workflow “PR Check – Debug artifacts after failure” dimulai di repositori
github/codeql-action - memantau artifact dari workflow yang sedang berjalan
- saat artifact muncul, mengunduhnya dan mengekstrak GITHUB_TOKEN
- membuat branch baru dengan token yang diekstrak
- melakukan push file kosong bernama
poc.txtke branch tersebut - membuat tag baru pada commit tersebut
- terus melakukan query apakah workflow “PR Check – Debug artifacts after failure” dimulai di repositori
- Karena ukuran artifact sekitar 21MB, dinilai ada peluang berhasil dalam batas waktu
- Setelah berhasil di repositori uji, skrip dijalankan terhadap repositori
github/codeql-action - Sekitar 2 jam kemudian workflow berjalan, dan skrip berhasil mengambil token lalu membuat branch, melakukan push file, serta membuat tag
Manipulasi tag yang memperbesar cakupan dampak
- Penyerang dapat menambahkan kode berbahaya ke branch yang tidak dilindungi menggunakan token tersebut
- Dengan cara yang lebih tersembunyi, strategi memasukkan perubahan berbahaya kecil ke feature branch sebelum merge lalu menunggu merge juga memungkinkan
- Izin membuat tag juga penting
- Jika tag
v3ditempelkan ke commit yang berisi kode berbahaya, pengguna yang menggunakancodeql-action@v3secara manual dapat menjalankan kode berbahaya tersebut
- Jika tag
- Dampak yang lebih besar berasal dari konfigurasi default CodeQL
- Ketika CodeQL diaktifkan dengan konfigurasi default dari pengaturan repositori, workflow GitHub Actions khusus yang tidak terlihat di daftar workflow repositori akan berjalan
- Workflow ini melakukan checkout repositori, inisialisasi CodeQL, scan CodeQL, dan unggah hasil
- Secara internal workflow menjalankan action dari repositori
github/codeql-actionpada commit yang ditunjuk oleh tag v3
- Saat itu tag
v3tidak immutable, dan workflow pinning yang direkomendasikan GitHub juga tidak digunakan - Jika penyerang memindahkan tag
v3ke commit berbahaya dengan GITHUB_TOKEN yang dikompromikan, repositori yang menggunakan workflow CodeQL default dapat menjalankan action CodeQL berbahaya - Karena action CodeQL melakukan checkout source code repositori target, action berbahaya dapat membocorkan source code dari repositori yang memakai konfigurasi default CodeQL
Jalur GitHub Actions Cache poisoning
- GITHUB_TOKEN pada action CodeQL default hanya memiliki izin read, sehingga dengan konfigurasi default saja tidak bisa langsung melakukan operasi tulis repositori, backdoor release, atau pencurian secrets melalui
workflow_dispatch - Sebagai gantinya, action CodeQL default berjalan dari main branch repositori
- Main branch pada repositori GitHub dapat menulis cache entry yang digunakan di seluruh repositori, sehingga muncul peluang GitHub Actions cache poisoning
- GitHub Actions Cache Poisoning adalah teknik yang dibahas dalam tulisan Adnan Khan, dan Cacheract adalah malware yang meninggalkan persistensi di build pipeline melalui cache poisoning
- Jika penyerang men-deploy Cacheract dari workflow CodeQL, alur berikut dimungkinkan:
- memprediksi cache entry
- menimpa entry tersebut dengan action berbahaya
- memperoleh eksekusi kode pada workflow yang menggunakan
actions/cache - mencuri GitHub Actions secrets dari workflow tersebut dan GITHUB_TOKEN dengan izin tinggi
- Meski action CodeQL berbahaya ditemukan dan kerentanannya ditangani, Cacheract tetap dapat terus melakukan cache poisoning
- Contoh repo besar yang terkonfirmasi menggunakan CodeQL bersama
actions/cacheantara lain Homebrew, Angular, dan Grafana
CVE-2025-24362 dan perbaikannya
- Sebagai hasil disclosure ini, CVE-2025-24362 ditetapkan
- GITHUB_TOKEN yang terekspos berada di dalam debug artifact yang diunggah CodeQL Action setelah workflow code scanning yang gagal
- Repositori CodeQL Actions memang sengaja memicu kegagalan, tetapi pengguna CodeQL Actions lain juga bisa saja mengekspos secrets mereka sebagai environment variable workflow jika kegagalan serupa terjadi
- Masalah ini diperbaiki di CodeQL Action 3.28.3
- Potensi dampak terbesar bukan pada CVE itu sendiri, melainkan pada jalur untuk mengeksploitasi kerentanan terhadap repositori CodeQL Actions dan melakukan serangan rantai pasok terhadap pengguna CodeQL
Respons GitHub dan mitigasi yang direkomendasikan
- Linimasa respons GitHub adalah sebagai berikut:
- 22 Januari 2025 15:13 UTC: Laporan disampaikan ke GitHub
- 22 Januari 2025 17:48 UTC: GitHub mengonfirmasi penerimaan
- 22 Januari 2025 18:28 UTC: GitHub mengonfirmasi kerentanan dan menonaktifkan sementara workflow “PR Check – Debug artifacts after failure”, serta mengajukan PR untuk menonaktifkan unggahan debug artifact
- 24 Januari 2025: GitHub menetapkan CVE-2025-24362 dan memublikasikan security advisory
- Langkah untuk mengurangi risiko paparan secret pada artifact workflow GitHub Actions adalah sebagai berikut:
- hanya mengunggah file atau direktori tertentu sebagai workflow artifact
- menghindari unggahan artifact yang menyertakan environment variable,
.git/config, dan file di direktori<path_to_runner_dir>/_work/_temp/milik runner - membatasi izin GITHUB_TOKEN menjadi read-only
- melakukan secret scan sebelum mengunggah artifact
1 komentar
Komentar di Hacker News
Jika GitHub lebih cepat mendorong immutable actions, dampak seperti ini pasti jauh lebih kecil
Saya terus mengulang bahwa fitur ini akan mencegah lebih dari 70% permukaan serangan GitHub Actions saat ini. Melihat insiden terjadi setiap minggu, rasanya sudah saatnya fitur ini dirilis
[1] https://github.com/features/preview/immutable-actions
Tidak ada penjelasan mengapa token sementara ini bahkan punya hak untuk membuat deployment baru dan menghasilkan attestasi artefak
Mereka mengatakan perbaikannya adalah mematikan log debug, tetapi tidak menjawab apakah hak token sementara sudah disesuaikan agar lebih tepat untuk mesin analisis kode
Dulu nilai default-nya hanya pengaturan permisif, jadi sayangnya pengaturan ini sering dipakai di organisasi dan repositori lama
Saat membuat repositori baru, repositori itu mewarisi nilai default dari organisasi induk, jadi jika tidak ada yang mengubahnya, default yang tidak aman ini tetap bertahan. Tidak ada pengaturan global untuk pengguna, sehingga repositori baru milik pribadi memakai default yang terbatas. Sejauh yang saya tahu, organisasi yang baru dibuat juga memakai default yang lebih baik
[0]: https://docs.github.com/en/actions/security-for-github-actio...
Saya semakin yakin bahwa CI dan CD harus menjadi lingkungan yang sepenuhnya terpisah. Jika CI ditembus, token terkait CD tidak boleh ikut bocor
Misalnya, wajib memenuhi kondisi seperti
"sub":"repo:octo-org/octo-repo:environment:prod"[1], dan jika ingin membuat sistem lebih kuat, bisa menambahkan [fun claims][] lain1: https://docs.github.com/en/actions/security-for-github-actio...
fun claims: https://github.com/github/actions-oidc-debugger#readme
Waktu responsnya bukan main. Respons GitHub cukup mengesankan
Sebagai orang dengan nama keluarga Prater, karena nama ini berasal dari Praetorian, saya benar-benar berharap bisa memiliki praetorian.com
Menggunakan GitHub Actions publik sama saja mencari masalah, apalagi jika Anda tidak menganalisis prosedur workflow-nya
Lebih baik meng-host sendiri woodpecker atau CI builder bagus lainnya (circle, travis, gitlab, dan sebagainya)
Kami telah menerapkan CodeQL pada PR OpenZFS. Ini bukan masalah bagi OpenZFS, karena kode kami bukan rahasia :)
Namun setidaknya syukurlah masalah ini cepat diselesaikan
Apakah ini sudah diperbaiki?
Situs ini performanya sangat buruk sampai saya hampir tidak bisa menggulir