flawopen.com/Teardowns/cve-2026-84973-jupyterlab-snapshot-checkout-toctou
CVE-2026-84973: Kerentanan TOCTOU pada alur snapshot JupyterLab
Pemeriksaan waktu berpresisi satu detik dapat membuat alur snapshot melakukan checkout dan menjalankan commit pull request yang belum disetujui dengan hak akses job. Perbarui update-snapshots-checkout ke versi 1.0.0 atau lebih baru.
Peninjau menyetujui paket tertentu, tetapi loket hanya memeriksa angka detik pada jam. Jika paket diganti pada detik yang sama, paket pengganti tampak ikut disetujui. Action ini membandingkan waktu dengan presisi satu detik dan menerima nilai yang sama, sehingga pembaruan pull request dapat lolos bersamaan dengan komentar maintainer.
Konsep Kunci & Istilah
TOCTOU- Time-of-check to time-of-use: keputusan keamanan dibuat untuk sumber daya yang berubah sebelum digunakan.
SHA head pull request- Pengenal commit yang tidak berubah di ujung cabang pull request. Alur kerja seharusnya hanya menjalankan commit persis yang disetujui.
Izin token GitHub Actions- Operasi repositori yang boleh dilakukan GITHUB_TOKEN milik job, seperti membaca atau menulis konten dan pull request.
CWE-367 / CWE-829- Advisory mengklasifikasikan kondisi balapan waktu sebagai
CWE-367dan eksekusi fungsi yang dikendalikan pull request sebagaiCWE-829.
Pemetaan kerangka kerja
Analisis Akar Masalah (Root Cause)
Sebelum versi 1.0.0, update-snapshots-checkout mengambil pushed_at dari pull request dan created_at dari komentar pemicu, mengubah keduanya menjadi detik Unix, lalu menolak proses hanya jika pushed_at lebih besar secara ketat. Kedua timestamp API berpresisi satu detik. Push dan komentar yang disetujui pada detik yang sama dapat bernilai sama dan lolos. Action lalu menyimpan SHA head saat ini dan memeriksanya setelah checkout; pemeriksaan itu hanya membuktikan checkout cocok dengan SHA yang baru diambil, bukan bahwa maintainer menyetujui commit tersebut. Perbaikan upstream mengganti -gt dengan -ge untuk menolak nilai sama maupun push yang lebih baru. Risiko hanya berlaku pada alur kerja yang memakai versi rentan lalu menjalankan konten pull request; dampaknya dibatasi oleh izin dan kredensial alur kerja.
Alur Serangan Langkah demi Langkah
Maintainer tepercaya memicu alur kerja
Pull request dibuka, lalu OWNER, COLLABORATOR, atau MEMBER mengirim komentar yang memicu alur pembaruan snapshot.
Pembaruan yang dikendalikan penyerang terjadi pada detik yang sama
Kontributor memperbarui cabang pull request pada detik yang sama. Presisi API satu detik memungkinkan nilai waktu Unix menjadi sama.
Perbandingan lebih-besar-ketat menerima nilai sama
Action rentan hanya menolak jika pushed_at lebih besar daripada created_at. Nilai sama tidak memenuhi kondisi itu sehingga SHA head baru dicatat.
Alur kerja melakukan checkout dan dapat menjalankan commit tersebut
Checkout cocok dengan SHA yang dicatat dan lolos pemeriksaan berikutnya. Jika langkah selanjutnya menjalankan action atau skrip dari pull request, izin dan kredensial job akan digunakan.
Perbarui dan kurangi kewenangan alur kerja
Perbarui ke 1.0.0 atau lebih baru. Pin action ke SHA yang tidak berubah, berikan GITHUB_TOKEN izin minimum, dan jauhkan kode pull request yang tidak tepercaya dari rahasia serta job istimewa.
Kode Sumber: Rentan vs Aman
Ini sesuai perbaikan satu baris upstream: -ge menolak nilai yang sama pada presisi waktu API. Perubahan ini menutup bypass pada detik yang sama. Tetap ikat persetujuan pada SHA yang tidak berubah dan minimalkan izin; urutan waktu bukan pengganti keputusan otorisasi yang tetap. Diff upstream mempertahankan pesan diagnostik yang ada; pesannya menyebut “setelah”, meskipun nilai yang sama kini juga ditolak.
if [[ $(date -d "$pushed_at" +%s) -gt $(date -d "$COMMENT_AT" +%s) ]]; then
echo "Updating is not allowed because the PR was pushed to (at $pushed_at) after the triggering comment was issued (at $COMMENT_AT)"
exit 1
fi
if [[ $(date -d "$pushed_at" +%s) -ge $(date -d "$COMMENT_AT" +%s) ]]; then
echo "Updating is not allowed because the PR was pushed to (at $pushed_at) after the triggering comment was issued (at $COMMENT_AT)"
exit 1
fi
Daftar Periksa Penguatan Sistem Rekayasa
- ✓Perbarui semua pemakaian update-snapshots-checkout ke 1.0.0 atau lebih baru; cari juga kode salinan dan fork.
- ✓Pin action eksternal maupun internal ke SHA tetap yang sudah ditinjau dan periksa perubahan sebelum memperbarui pin.
- ✓Jangan menyetujui cabang pull request yang bergerak hanya berdasarkan timestamp; ikat persetujuan ke SHA head yang tepat.
- ✓Tetapkan izin minimum eksplisit per job dan hilangkan contents: write serta pull-requests: write bila tidak diperlukan.
- ✓Jauhkan rahasia dan kredensial deployment berhak istimewa dari job yang menjalankan kode pull request eksternal.
- ✓Tambahkan uji regresi yang menolak timestamp sama maupun push yang lebih baru.