FlawOpen

flawopen.com/Teardowns/cve-2024-32002-git-submodule-rce

● CVE-2024-32002 · CVSS 9.0 · Kritis
Riset Keamanan · FlawOpen

CVE-2024-32002: Eksekusi Kode Jarak Jauh Symlink Submodul Git (RCE)

CVE-2024-32002 memungkinkan repositori Git yang disiapkan khusus menulis ke .git melalui symlink dengan benturan huruf besar-kecil saat clone rekursif, sehingga hook dapat berjalan sebelum pemeriksaan. Perbaikan upstream Git memeriksa tujuan submodul sebelum dan sesudah clone serta membatalkan operasi jika ada konten tak terduga; tingkatkan Git ke rilis yang telah diperbaiki.

💡 Penjelasan Sederhana (ELI5)

Bayangkan gudang dengan papan petunjuk yang menganggap A dan a sebagai pintu yang sama. Jika jalur submodul melewati petunjuk yang mengarah ke ruang arsip (.git), berkas untuk satu rak bisa masuk ke catatan kendali Git. Perbaikan Git memeriksa tujuan sebelum dan sesudah clone, lalu berhenti jika menemukan isi yang tidak terduga.

Konsep Kunci & Istilah

Submodul Git
Repositori Git terpisah yang disematkan sebagai subdirektori di repositori induk.
Symlink (Tautan Simbolis)
Objek sistem file yang mengarahkan traversal jalur ke target lain.
Tabrakan Huruf Besar/Kecil
Perilaku NTFS dan APFS di mana jalur yang hanya berbeda huruf besar/kecil merujuk ke file yang sama.
Git Hooks
Skrip yang dapat dieksekusi di .git/hooks/ yang dipicu secara otomatis oleh post-checkout.

Pemetaan kerangka kerja

Analisis Akar Masalah (Root Cause)

Pada sistem berkas yang tidak peka huruf besar-kecil dan mendukung symlink, repositori yang disiapkan khusus dapat memberi submodul jalur yang bertabrakan dengan symlink setelah pelipatan huruf. Saat clone rekursif, Git dapat mengganti direktori yang dibuat untuk clone dengan symlink tersebut dan menulis berkas di luar worktree submodul ke dalam .git. Hook yang ditempatkan di sana dapat berjalan sebelum pengguna memeriksa checkout. Patch upstream menolak clone ke tujuan submodul yang sudah ada dan tidak kosong, lalu setelah clone menolak tujuan yang berisi hal selain metadata .git.

Alur Serangan Langkah demi Langkah

Langkah 1

Clone rekursif memproses metadata yang dikendalikan repositori

Pengguna melakukan clone rekursif pada repositori yang tidak tepercaya di sistem berkas peka huruf besar-kecil yang mendukung symlink. Repositori menyediakan jalur submodul dan entri terlacak yang bertabrakan setelah pelipatan huruf.

Langkah 2

Benturan jalur melewati batas kepercayaan

Git dapat menyelesaikan jalur submodul yang bertabrakan melalui symlink, bukan ke dalam worktree submodul yang dimaksud. Batas yang terdampak adalah penanganan jalur sistem berkas oleh Git saat clone submodul rekursif.

Langkah 3

Berkas masuk ke metadata Git

Penulisan yang dialihkan dapat menempatkan hook di area .git repositori. Pemberitahuan proyek Git mengonfirmasi hook dapat ditulis di sana dan dijalankan saat clone masih berlangsung.

Langkah 4

Clone dapat menjalankan kode sebelum ditinjau

Git menjalankan hook sebagai bagian dari operasi clone, sebelum pengguna sempat memeriksa berkas checkout. Rilis Git yang diperbaiki memeriksa kondisi tujuan dan membatalkan operasi jika menemukan berkas yang tak terduga.

Kode Sumber: Rentan vs Aman

Ini adalah cuplikan perubahan C upstream Git di clone_submodule(), bukan fungsi yang dapat berdiri sendiri. Sebelum diperbaiki, jalur clone yang ditampilkan tidak memiliki pemeriksaan isi tujuan yang sesuai. Perbaikan menolak direktori checkout yang sudah ada dan tidak kosong, lalu setelah clone memastikan hanya metadata .git yang tersisa; fungsi pembantu memeriksa entri direktori. Implementasi lengkap tersedia di commit upstream.

IMPLEMENTASI RENTAN
if (!file_exists(sm_gitdir)) {
    if (safe_create_leading_directories_const(sm_gitdir) < 0)
        die(_("could not create directory '%s'"), sm_gitdir);

    if (run_command(&cp))
        die(_("clone of '%s' into submodule path '%s' failed"),
            clone_data->url, clone_data_path);
}
PERBAIKAN AMAN & KUAT
struct stat st;

if (!file_exists(sm_gitdir)) {
    if (clone_data->require_init && !stat(clone_data_path, &st) &&
        !is_empty_dir(clone_data_path))
        die(_("directory not empty: '%s'"), clone_data_path);

    if (safe_create_leading_directories_const(sm_gitdir) < 0)
        die(_("could not create directory '%s'"), sm_gitdir);

    if (run_command(&cp))
        die(_("clone of '%s' into submodule path '%s' failed"),
            clone_data->url, clone_data_path);

    if (clone_data->require_init && !stat(clone_data_path, &st) &&
        !dir_contains_only_dotgit(clone_data_path)) {
        char *dot_git = xstrfmt("%s/.git", clone_data_path);
        unlink(dot_git);
        free(dot_git);
        die(_("directory not empty: '%s'"), clone_data_path);
    }
}

Daftar Periksa Penguatan Sistem Rekayasa

Sumber