1 poin oleh GN⁺ 1 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • gokrazy/rsync adalah implementasi rsync minimal yang ditulis dalam Go, dan ditinjau berdasarkan 12 kerentanan rsync yang dipublikasikan pada Januari 2025 dan Mei 2026
  • Pemeriksaan batas Go dan inisialisasi nol mengubah heap overflow serta kebocoran informasi stack menjadi panic atau nilai yang tidak berbahaya, tetapi panic tetap dapat menjadi serangan denial-of-service
  • Untuk keluarga path traversal dan TOCTOU, API file tahan traversal seperti os.Root di Go 1.24 menjadi pertahanan utama, dan gokrazy/rsync telah sepenuhnya beralih ke sana
  • Strategi implementasi minimal mengurangi permukaan serangan dengan menghindari kerentanan yang terkait dengan fitur yang belum diimplementasikan seperti --inc-recursive, kompresi, --safe-links, proxy, dan ACL nama host
  • Sebagian besar kerentanan berasal dari kurangnya validasi dan kompleksitas yang berlebihan, dan untuk kasus penggunaan yang sederhana, implementasi yang sederhana bisa jadi lebih tepat

Latar belakang dan cakupan

  • Pada Januari 2025, beberapa peneliti keamanan mengungkap total 6 kerentanan keamanan di upstream Samba rsync, dan sebagian di antaranya memungkinkan eksekusi kode arbitrer serta kebocoran file
  • Fokus peninjauan utama adalah apakah gokrazy/rsync, implementasi kompatibel dan minimal yang ditulis dalam Go, benar-benar dapat menghindari keluarga kerentanan semacam ini
  • Objek analisis adalah 12 kerentanan gabungan dari gelombang Januari 2025 dan gelombang Mei 2026
  • Jika Anda menjalankan upstream rsync di produksi, Anda harus memutakhirkan ke 3.4.3 atau lebih baru, dan gokrazy/rsync harus dinaikkan ke v0.3.3 atau lebih baru
  • gokrazy/rsync ditulis untuk menyediakan paket perangkat lunak dari proyek riset distribusi Linux distri di router7, dan router7 berbasis pada platform appliance Go gokrazy
  • Awalnya hanya ada server rsync, tetapi sekarang mendukung semua arah dan digunakan di beberapa server gokrazy/rsync sebagai fungsi dasar rsync yang dapat ditautkan ke program Go

Kerentanan Januari 2025

  • CVE-2024-12084: heap buffer overflow, tingkat keparahan 9.8

    • rsync membandingkan panjang checksum yang diterima dari jaringan dengan MAX_DIGEST_LEN, tetapi struktur data internalnya selalu menggunakan buffer 16 byte char sum2[SUM_LENGTH]
    • MAX_DIGEST_LEN dapat menjadi lebih besar saat dikompilasi dengan dukungan checksum SHA256 atau SHA512, sehingga penyerang dapat menulis melampaui batas buffer sum2 hingga 48 byte
    • Masalah ini diperkenalkan pada commit September 2022 commit ae16850 yang menambahkan dukungan checksum SHA256/SHA512
    • Perbaikan upstream mengganti sum2 menjadi sum2_array yang dialokasikan secara dinamis, lalu mengalokasikan dan memeriksanya berdasarkan xfer_sum_len, yaitu panjang checksum dari algoritme transfer
    • Di Go, pemeriksaan batas yang salah tidak berujung pada heap buffer overflow, melainkan memicu panic lewat pemeriksaan batas runtime
    • gokrazy/rsync juga memiliki validasi sum header yang hilang, tetapi bukan karena kekeliruan ukuran; jika ChecksumLength diubah menjadi 512, runtime Go akan memunculkan panic: runtime error: slice bounds out of range [:512] with length 16
    • Karena crash seluruh server bukan mode kegagalan yang diinginkan, pemeriksaan batas yang hilang ditambahkan agar panic berubah menjadi error
  • CVE-2024-12085: kebocoran informasi stack untuk bypass ASLR, tingkat keparahan 7.5

    • Karena validasi yang hilang sama seperti pada CVE-2024-12084, penyerang dapat memilih algoritme checksum pendek lalu mengklaim telah mengirim checksum yang lebih panjang
    • Menurut Google Security report, jika heap buffer overflow digabungkan dengan kebocoran informasi, klien anonim yang hanya memiliki akses baca dapat mengeksekusi kode arbitrer di mesin server rsync
    • hash_search() membuat digest chunk di char sum2[MAX_DIGEST_LEN] pada stack dan membandingkannya dengan memcmp(), tetapi buffer stack lokal sum2 tidak diinisialisasi sehingga byte-byte sisa dapat berisi isi stack
    • Klien berbahaya dapat membocorkan 1 byte per unduhan file, dan data yang bocor dapat mencakup pointer objek heap, stack cookie, variabel lokal, pointer variabel global, dan return pointer
    • “Some checksum buffer fixes” memastikan s->s2length yang dikendalikan penyerang tidak bisa lebih besar daripada panjang checksum transfer, dan “prevent information leak off the stack” menginisialisasi memori sum2 ke 0
    • Go menginisialisasi semua variabel ke zero value, sehingga tidak terdampak oleh kerentanan ini, dan gokrazy/rsync mengimplementasikan protokol versi 27, bukan versi 30 yang memperkenalkan pemilihan checksum selain MD4
  • CVE-2024-12087: path traversal menggunakan symbolic link, tingkat keparahan 7.5

    • Menurut Google Security report, saat sinkronisasi symbolic link diaktifkan dengan -l atau -a (--archive), server berbahaya dapat membuat klien menulis file arbitrer di luar direktori tujuan
    • Serangan dilakukan dengan mengirim beberapa daftar file dalam mode --inc-recursive; pada daftar pertama, symlink dibuat sebagai direktori, lalu pada daftar berikutnya nama yang sama diubah menjadi symbolic link yang menunjuk ke luar direktori tujuan
    • Go sendiri tidak dapat mencegah kerentanan ini; penyebabnya adalah kesalahan logika karena beberapa daftar file digabungkan lalu tidak divalidasi ulang
    • Perbaikan upstream menambahkan validasi yang sebelumnya hilang
    • gokrazy/rsync tidak terdampak karena tidak mengimplementasikan mode incremental recursion (--inc-recursive)
    • incremental recursion memungkinkan pemrosesan dengan cara “windowed” tanpa memindai seluruh kumpulan file sebelum transfer dimulai, tetapi ada trade-off antara kompleksitas implementasi dan penggunaan sumber daya
  • CVE-2024-12088: bypass --safe-links, tingkat keparahan 7.5

    • Menurut Google Security report, --safe-links adalah fitur yang memverifikasi bahwa symbolic link yang diterima dari server menunjuk ke dalam direktori tujuan
    • Bypass terjadi karena tidak mempertimbangkan apakah ada symbolic link lain di tengah jalur target symbolic link
    • Sebagai contoh, jika ada {DESTINATION}/a -> . dan {DESTINATION}/foo -> a/a/a/a/a/a/../../, maka foo sebenarnya menunjuk ke luar direktori tujuan, tetapi unsafe_symlink() menganggap a/ sebagai direktori dan menilainya aman
    • Perbaikan upstream memperketat unsafe_symlink() agar tidak mengizinkan ../ di posisi selain awal jalur
    • Go sendiri tidak dapat mencegah fungsi validasi yang salah, dan gokrazy/rsync belum mengimplementasikan fitur --safe-links sehingga tidak rentan
  • CVE-2024-12086: kebocoran file arbitrer, tingkat keparahan 6.8

    • Receiver rsync dalam mode klien tidak membersihkan nama file yang diberikan oleh sender rsync, dan gagal mencegah pembukaan file di luar tree tujuan
    • Sender berbahaya dapat mengarahkan receiver untuk membandingkan checksum file arbitrer di luar tree tujuan, lalu mengamati respons receiver terhadap checksum 1 byte untuk membocorkan file arbitrer
    • Menurut Google Security report, jika klien terhubung ke server berbahaya, server dapat membocorkan isi file arbitrer dari mesin klien
    • Perbaikan upstream memvalidasi jalur yang diberikan sender untuk mencegah pembukaan file di luar tree tujuan
    • Go memiliki API yang dapat mencegah hal ini, dan os.Root di Go diajukan sebagai pertahanan terkait
    • gokrazy/rsync tidak rentan karena mengimplementasikan protokol versi 27, bukan versi 29 yang memperkenalkan fitur fuzzy matching
  • CVE-2024-12747: race condition symbolic link, tingkat keparahan 5.6

    • Menurut Red Hat Security Advisory, ini adalah cacat yang muncul dari race condition selama penanganan symbolic link di rsync
    • Perilaku default rsync adalah melewati symbolic link saat ditemukan, tetapi jika penyerang mengganti file biasa menjadi symbolic link pada waktu yang tepat, perilaku default itu dapat dilewati sehingga symbolic link tersebut diikuti
  • Perbaikan upstream mengubah agar pemanggilan open() pada sender rsync menggunakan opsi O_NOFOLLOW

    • gokrazy/rsync rentan hingga sebelum commit 1b1fbf6, dan commit ini memperkenalkan mitigasi O_NOFOLLOW yang sama seperti rsync upstream
    • Damien Neil menilai perbaikan CVE-2024-12747 di gokrazy tidak memadai, karena O_NOFOLLOW hanya mencegah penelusuran symbolic link pada komponen terakhir jalur
    • Sebagai contoh, pada os.Open("dir/passwd"), jika komponen jalur sebelumnya yaitu dir diganti menjadi symbolic link yang mengarah ke /etc, cara ini tetap bisa dilewati
    • Masalah ini dilaporkan ke kontak keamanan rsync pada April 2025 dan berujung pada CVE-2026-29518 yang dipublikasikan pada 2026-05-20

Kerentanan Mei 2026

  • CVE-2026-29518: kondisi balapan symbolic link, tingkat keparahan 7.0

    • Menurut entri NEWS rsync 3.4.3, ini adalah kondisi balapan symbolic link TOCTOU yang memungkinkan eskalasi hak akses lokal dalam mode daemon tanpa chroot
    • Daemon rsync yang dikonfigurasi dengan use chroot = no terekspos pada balapan time-of-check/time-of-use terhadap komponen path induk
    • Penyerang lokal yang memiliki akses tulis ke modul dapat mengganti komponen parent directory dengan symbolic link di antara pemeriksaan receiver dan open(), sehingga menyebabkan pengungkapan basis-file saat membaca, dan penimpaan file di luar modul saat menulis
    • Nilai bawaan use chroot = yes tidak terekspos
    • Perbaikan upstream menggunakan secure_relative_open() yang mirip dengan API os.Root milik Go
    • gokrazy/rsync sempat rentan sampai beralih ke API os.Root yang tahan traversal pada sender dan receiver
  • CVE-2026-43618: integer overflow menyebabkan kebocoran memori jarak jauh, tingkat keparahan 8.1

    • Decoder token kompresi pada receiver rsync mengakumulasi penghitung signed 32-bit tanpa pemeriksaan overflow, sehingga pengirim berbahaya bisa membocorkan isi memori proses
    • Data yang bocor dapat mencakup variabel lingkungan, kata sandi, pointer heap dan library, yang dapat melemahkan ASLR dan mempermudah eksploitasi lanjutan
    • Dampaknya berlaku pada koneksi daemon terautentikasi dengan kompresi aktif, dan secara bawaan aktif pada protokol 30 atau lebih tinggi jika kedua peer mengiklankan kompresi
    • Mitigasinya adalah menonaktifkan kompresi daemon dengan refuse options = compress di rsyncd.conf
    • Perbaikan upstream menambahkan pemeriksaan yang sebelumnya hilang
    • gokrazy/rsync tidak mengimplementasikan kompresi, sehingga tidak rentan, dan alasan mengapa dukungan kompresi tidak sesederhana kelihatannya dirangkum dalam gokrazy/rsync issue #35
  • CVE-2026-43620: denial-of-service setelah pembacaan di luar batas, tingkat keparahan 6.5

    • Ini terjadi karena guard parent_ndx<0 yang ditambahkan ke send_files() pada 2025 tidak diterapkan pada blok recv_files() yang tampak identik secara visual
    • Jika server rsync berbahaya mengirim flag kompatibilitas CF_INC_RECURSE dan flist yang salah bentuk, receiver dapat membaca dan melakukan dereferensi dir_flist->files[-1], yang berujung pada SIGSEGV deterministik
    • Dampaknya berlaku pada semua klien rsync yang melakukan pull biasa dari URL yang dikendalikan penyerang, tanpa memerlukan opsi khusus di sisi korban karena inc_recurse adalah bawaan pada protokol 30 ke atas
    • Menggunakan --no-inc-recursive di klien adalah mitigasinya, dan perbaikan upstream menambahkan guard parent_ndx<0 juga ke recv_files()
    • Karena gokrazy/rsync tidak mengimplementasikan mode incremental recursive --inc-recursive, proyek ini tidak terdampak, sama seperti pada CVE-2024-12087
  • CVE-2026-43619: kondisi balapan symbolic link tambahan, tingkat keparahan 6.3

    • Perbaikan untuk kondisi balapan symbolic link pada panggilan open() receiver (CVE-2026-29518) tidak diterapkan pada syscall berbasis path lain seperti chmod, lchown, utimes, rename, unlink, mkdir, symlink, mknod, link, rmdir, dan lstat
    • Pada daemon rsync yang dikonfigurasi dengan use chroot = no, penyerang lokal dapat mengganti komponen direktori induk dengan symbolic link di antara pemeriksaan receiver dan syscall, lalu mengalihkan operasi ke luar modul yang diekspor
    • Nilai bawaan use chroot = yes tidak terekspos
    • Perbaikan upstream menangani syscall berbasis path yang terdampak melalui dirfd induk yang dibuka di bawah pembatasan yang dipaksakan kernel, seperti openat2 pada Linux 5.6+, O_RESOLVE_BENEATH pada FreeBSD 13+ dan macOS 15+, atau traversal O_NOFOLLOW per komponen pada lingkungan lain
    • gokrazy/rsync tidak terdampak karena secara menyeluruh menggunakan API os.Root milik Go
  • CVE-2026-43617: bypass ACL berbasis hostname, tingkat keparahan 4.8

    • Pada daemon rsync dengan pengaturan rsyncd.conf global daemon chroot = /X, lookup DNS balik untuk klien yang terhubung dilakukan setelah daemon melakukan chroot ke /X
    • Jika /X tidak memiliki /etc/resolv.conf, /etc/nsswitch.conf, /etc/hosts, dan modul layanan NSS yang diperlukan untuk resolusi glibc, lookup akan gagal dan hostname koneksi disetel menjadi "UNKNOWN"
    • Akibatnya, aturan deny berbasis hostname seperti hosts deny = *.evil.example tidak akan cocok, sehingga penyerang yang mengendalikan PTR record dapat terhubung dari hostname yang sebenarnya ingin diblokir administrator
    • ACL berbasis IP tidak terdampak, dan pengaturan use chroot per modul tidak terkait dengan kerentanan ini
    • Perbaikan upstream memindahkan lookup DNS ke tahap yang lebih awal dalam protokol
    • gokrazy/rsync tidak mengimplementasikan daftar allow/deny berbasis hostname dan hanya mengimplementasikan daftar allow/deny berbasis IP, sehingga tidak rentan
  • CVE-2026-45232: penulisan stack di luar batas, tingkat keparahan 3.1

    • Dukungan proksi HTTP CONNECT pada klien rsync memiliki penulisan stack di luar batas akibat off-by-one di establish_proxy_connection()
    • Jika proksi atau penyerang man-in-the-middle mengembalikan lebih dari 1023 byte tanpa '\n' pada baris respons pertama, kode berikutnya dapat menulis '\0' tepat setelah buffer 1024 byte dan merusak slot stack yang berdekatan
    • AddressSanitizer melaporkan stack-buffer-overflow pada socket.c:95 di frame establish_proxy_connection
    • Perbaikan upstream memvalidasi data yang diberikan penyerang
    • gokrazy/rsync tidak mengimplementasikan dukungan proksi seperti ini, sehingga tidak rentan

Apa yang benar-benar dicegah oleh Go dan gokrazy/rsync

  • Pemeriksaan batas di runtime Go mengubah masalah keamanan yang lebih serius menjadi panic, dan panic tetap merupakan risiko penolakan layanan tetapi dinilai sebagai mode kegagalan yang lebih baik
  • Go menginisialisasi memori ke 0 sehingga kebocoran informasi seperti CVE-2024-12085 menjadi tidak mungkin terjadi
  • API os.Root milik Go mencegah sebagian besar kerentanan yang tersisa
  • Dari 12 kerentanan, hanya CVE-2026-43617 yang diklasifikasikan sebagai bug logika aplikasi yang tidak dapat dicegah hanya dengan penggunaan Go
  • Perbedaan utama antara gokrazy/rsync dan rsync upstream resmi, selain ditulis dalam Go, adalah bahwa implementasinya diminimalkan
  • gokrazy/rsync tidak mengimplementasikan berbagai fitur yang bermasalah seperti --inc-recursive, --safe-links, kompresi, proxy, dan ACL nama host, sehingga terhindar dari banyak kerentanan
  • Seperti semua implementasi rsync yang kompatibel dengan wire protocol, gokrazy/rsync menargetkan versi protokol 27, dan versi protokol setelah itu memperkenalkan kompleksitas yang cukup besar
  • Status gokrazy/rsync per CVE pada saat publikasi:
    • 2024-12084: implementasinya ada dan memicu panic
    • 2024-12085: fitur protokol 30, jadi tidak rentan karena tidak diimplementasikan
    • 2024-12086: fitur protokol 29, jadi tidak rentan karena tidak diimplementasikan
    • 2024-12087: tidak rentan karena inc-rec tidak diimplementasikan
    • 2024-12088: tidak rentan karena safe-links tidak diimplementasikan
    • 2024-12747: implementasinya ada dan rentan
    • 2026-29518: implementasinya ada dan sudah ditambal
    • 2026-43617: tidak rentan karena daftar host deny tidak diimplementasikan
    • 2026-43618: tidak rentan karena kompresi tidak diimplementasikan
    • 2026-43619: implementasinya ada dan sudah ditambal
    • 2026-43620: tidak rentan karena inc-rec tidak diimplementasikan
    • 2026-45232: tidak rentan karena proxy tidak diimplementasikan
  • Semua kerentanan yang diketahui pada gokrazy/rsync telah diperbaiki, dan status di atas menunjukkan kondisinya pada saat tiap CVE dipublikasikan
  • Saat kerentanan diumumkan pada Januari 2025, gokrazy/rsync memicu panic pada CVE-2024-12084 dan rentan terhadap race condition TOCTOU pada CVE-2024-12747
  • Dalam proses memperbaiki masalah TOCTOU, CVE-2026-29518 ditemukan, dan telah diperbaiki di gokrazy/rsync sebelum CVE tersebut dipublikasikan
  • CVE-2026-43619 ditemukan belakangan, tetapi di gokrazy/rsync sebenarnya sudah terselesaikan melalui perbaikan yang sama, yaitu penggunaan penuh os.Root dari Go

Pemisahan peran dan penamaan kerentanan

  • Banyak laporan kerentanan menggunakan istilah “server” dan “client”, tetapi dalam transfer rsync, baik klien maupun server rsync dapat berperan sebagai pengirim (sender, unggah file) atau penerima (receiver, unduh file)
  • Dalam mode daemon, akses filesystem dapat dibatasi ke jalur modul yang telah dikonfigurasi sebelumnya, tetapi dalam command mode hal itu tidak berlaku
  • Empat konfigurasi dan lapisan peran/protokol dapat dilihat pada diagram rsync combinations
  • Judul asli untuk kerentanan Arbitrary File Leak (CVE-2024-12086), yaitu “Server leaks arbitrary client files”, mudah menimbulkan salah paham
  • Ungkapan yang lebih tepat adalah bahwa penerima rsync membocorkan file arbitrer kepada pengirim yang berbahaya
  • Klien pengirim yang berbahaya dapat, dalam lingkungan seperti command mode melalui SSH, membuat rsync jarak jauh yang belum ditambal membuka file di luar pohon target, misalnya basis data kata sandi sistem /etc/shadow
  • Dalam mode daemon, server mengaktifkan normalisasi jalur tambahan (path sanitization) untuk mencegah serangan ini
  • Kerentanan Symlink Path Traversal (CVE-2024-12087) juga digambarkan sebagai “malicious server”, tetapi yang tepat adalah pengirim yang berbahaya, yang bisa berupa klien maupun server

Perbandingan dengan OpenBSD openrsync

  • Proyek OpenBSD dikenal berfokus pada keamanan, dan openrsync tidak terdampak Heap Buffer Overflow (CVE-2024-12084) maupun Stack Info Leak (CVE-2024-12085) karena memverifikasi panjang checksum dan hanya mendukung MD4 sebagai satu-satunya ukuran/algoritme checksum
  • Seperti gokrazy/rsync, openrsync tidak terdampak CVE-2024-12086, CVE-2024-12087, dan CVE-2024-12088 karena fitur terkait tidak diimplementasikan
  • Bahkan jika rentan, saat dijalankan di OpenBSD, pertahanan berlapis yang membatasi akses filesystem melalui OpenBSD unveil(2) dan pledge(2) mungkin dapat mencegah eksploitasi yang berhasil
  • openrsync tidak terdampak CVE-2024-12747 karena sejak awal implementasi dukungan symbolic link, ia menggunakan O_NOFOLLOW
  • Namun, O_NOFOLLOW bukan perbaikan yang memadai untuk masalah ini, sehingga openrsync terdampak CVE-2026-29518
  • Paket kerentanan Mei 2026 juga serupa dalam hal sebagian besar fitur terkait tidak diimplementasikan
  • openrsync tidak terdampak sebagian besar kerentanan yang dilaporkan karena mengimplementasikan validasi dengan baik, membatasi attack surface, dan menerapkan pertahanan berlapis

Pertahanan berlapis dan os.Root

  • Linux mount namespace

    • Dalam beberapa minggu setelah memulai proyek gokrazy/rsync, ditambahkan fitur yang mendukung penurunan hak istimewa serta penggunaan mount/pid namespace di Linux untuk membatasi akses ke objek filesystem
    • Pendekatan ini bekerja baik untuk memitigasi serangan traversal path, tetapi memerlukan hak istimewa sehingga harus dijalankan sebagai root atau di dalam Linux user namespace jika fitur itu diaktifkan pada distro/sistem
    • Mount namespace cocok untuk konfigurasi server, tetapi sering kali tidak dapat digunakan untuk transfer interaktif satu kali yang dijalankan dengan akun pengguna biasa
  • Hardening systemd

    • Commit yang sama yang memperkenalkan dukungan Linux mount/pid namespace juga menyertakan file layanan systemd yang membatasi akses filesystem ke direktori home, dan README merekomendasikan untuk membatasi akses filesystem lebih jauh sesuai use case
    • Jika pembatasan filesystem ini dikonfigurasi dengan benar, hal itu memitigasi kerentanan File Leak (CVE-2024-12086) dan Path Traversal (CVE-2024-12087)
    • Symlink Race Condition (CVE-2024-12747) bergantung pada eskalasi hak istimewa melalui proses rsync, tetapi berkat fitur DynamicUser, proses tersebut memiliki hak yang lebih sedikit daripada pengguna lain
    • Seperti mount namespace, ini bagus untuk konfigurasi server tetapi merepotkan untuk disetel bagi penggunaan interaktif satu kali
  • Linux Landlock

    • Melalui Porting OpenBSD pledge() to Linux (2022), penulis diingatkan bahwa Linux juga memiliki Landlock API, kontrol akses non-privileged dan per-proses yang mirip dengan unveil(2) milik OpenBSD
    • Ide dasarnya adalah setelah program mengetahui direktori yang akan dikerjakan, ia dapat memanggil sesuatu seperti unveil("/home/michael/backups", "rw"); agar tidak lagi bisa mengakses lokasi filesystem di luar path tersebut
    • Pada Maret 2025, dukungan Landlock diimplementasikan untuk membatasi akses filesystem
    • Setelah konfigurasi diterapkan, bahkan eksekusi gokrazy/rsync tanpa hak istimewa pun dapat membatasi transfer rsync menjadi hanya-baca pada sumber dan baca-tulis pada direktori tujuan
    • Kekurangannya adalah Landlock bekerja pada tingkat proses
    • Kebijakan Landlock juga harus mencakup file yang diperlukan program; misalnya, gokrazy/rsync harus bisa membaca /etc/passwd untuk lookup ID pengguna, jadi jika penyerang menargetkan /etc/passwd, Landlock tidak akan membantu
  • os.Root di Go

    • Pada Februari 2025, Go 1.24 memperkenalkan API os.Root yang tahan terhadap traversal path, dan latar belakang terkait dirangkum dalam The Go Blog: Traversal-resistant file APIs oleh Damien Neil
    • Dibandingkan Landlock, os.Root memberikan kontrol yang lebih rinci untuk setiap operasi filesystem
    • Go 1.25 yang dirilis pada Agustus 2025 menambahkan lebih banyak metode ke os.Root, menjadikannya pilihan yang nyaman untuk sebagian besar penggunaan filesystem
    • Semua penggunaan filesystem di gokrazy/rsync telah dialihkan ke os.Root, dan ini sangat cocok dengan model di mana pengguna mengonfigurasi direktori input/output, tetapi nama file yang diterima lewat jaringan tidak dapat dipercaya
    • Bahkan system call yang tampaknya tidak bisa dibuat langsung lewat API seperti mknod(2) pun dapat digunakan dengan aman
    • Damien Neil menjelaskan bahwa dengan os.Root.OpenFile kita bisa membuka direktori induk target, memperoleh file descriptor direktori tersebut lewat File.Fd, lalu membuat file dengan golang.org/x/sys/unix#Mknodat
    • Contoh penggunaan nyata ada di internal/receiver/generatormknod_linux.go, line 15-29
    • Linux memiliki mknodat(2), tetapi hingga Linux 7.0 tidak ada bindat yang menjadi padanan untuk bind(2)
    • Lennart Poettering mengusulkan trik untuk melewati resolusi path tanpa bindat, yaitu dengan melakukan bind ke /proc/self/<fd>/foobar
    • Jika setelah /proc/self/<fd> yang sudah diketahui aman ditentukan bukan sebuah path melainkan basename, yaitu komponen path terakhir saja, resolusi path akan dilewati, dan kode terkaitnya ada di line 49-56
    • Berkat dua tips ini, gokrazy/rsync v0.3.1 dan yang lebih baru sepenuhnya menggunakan os.Root, sehingga semua akses filesystem memiliki keamanan traversal path

Pelajaran utama

  • Semua kerentanan selain kerentanan TOCTOU (CVE-2024-12747, CVE-2026-29518, CVE-2026-43619) berasal dari tidak adanya validasi input atau validasi input yang salah
  • Pada tiga kasus memang sejak awal tidak ada validasi, dan CVE-2024-12088 adalah kasus ketika validasi yang ada tidak mampu menangani semua edge case karena topik resolusi path filesystem memang rumit
  • Perbaikan struktural yang paling bernilai adalah menyediakan validasi yang selalu aktif seperti pemeriksaan batas dan API yang aman secara default seperti os.Root milik Go
  • Beberapa kerentanan muncul dari evolusi protokol rsync; fitur baru ditambahkan ke kode yang semula memiliki validasi memadai, tetapi validasinya tidak diperbarui dengan benar
  • Negosiasi algoritme checksum dan incremental recursion ditambahkan pada protokol versi 30, dan validasi yang ada tidak diperbarui agar sesuai dengan cara penanganan fitur baru tersebut
  • gokrazy/rsync dan openrsync tidak rentan terhadap 8 dari 12 kerentanan keamanan hanya karena mereka tidak mengimplementasikan fitur yang rentan
  • Fitur-fitur tersebut ditambahkan ke rsync karena pada suatu titik memang bernilai bagi seseorang, dan ini tidak berarti pengembangan perangkat lunak harus dihentikan
  • Pilihan ideal adalah menggunakan implementasi dengan kompleksitas yang sesuai dan proporsional dengan kompleksitas use case; pilih implementasi sederhana untuk use case sederhana, dan pilih implementasi penuh fitur hanya saat diperlukan

1 komentar

 
GN⁺ 1 jam lalu
Komentar Lobste.rs
  • Tulisan yang luar biasa. Begitu bagusnya sampai semua bahasa seharusnya memasukkan API seperti os.Root ke pustaka standarnya
    Setelah mengalami beberapa kerentanan path traversal di SecureDrop, kami memakai versi yang sangat disederhanakan, dan sekarang dengan menggunakan API yang benar, satu kelas kerentanan bisa hilang sepenuhnya
    • Benar. Tokoh utama dari tulisan blog ini tampaknya bukan Go, melainkan os.Root