1 puan yazan GN⁺ 2 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • gokrazy/rsync, Go ile yazılmış minimal bir rsync uygulamasıdır ve Ocak 2025 ile Mayıs 2026’da açıklanan 12 rsync güvenlik açığı temel alınarak incelenmiştir
  • Go’nun sınır denetimleri ve 0 ile başlatma davranışı, heap taşmasını ve stack bilgi sızıntısını panic’e ya da zararsız değerlere dönüştürür; ancak panic yine de hizmet reddine yol açabilir
  • Dizin geçişi ve TOCTOU sınıfı sorunlarda, Go 1.24’teki os.Root gibi geçişe dayanıklı dosya API’leri temel savunma haline gelir; gokrazy/rsync buna tamamen geçirilmiştir
  • Minimal uygulama stratejisi, --inc-recursive, sıkıştırma, --safe-links, proxy ve ana makine adı ACL’leri gibi uygulanmamış özelliklerle ilgili açıkları önleyerek saldırı yüzeyini azaltır
  • Güvenlik açıklarının çoğu eksik doğrulama ve aşırı karmaşıklıktan kaynaklanmıştır; basit kullanım senaryoları için basit bir uygulama daha uygun olabilir

Arka plan ve kapsam

  • Ocak 2025’te çeşitli güvenlik araştırmacıları, upstream Samba rsync içinde toplam 6 güvenlik açığı açıkladı; bunların bazıları rastgele kod yürütmeye ve dosya sızdırmaya izin veriyordu
  • Go ile yazılmış uyumlu ve minimal bir uygulama olan gokrazy/rsync’in bu tür güvenlik açığı sınıflarından gerçekten kaçınıp kaçınamayacağı incelemenin ana konusudur
  • Analizin kapsamı, Ocak 2025 partisi ile Mayıs 2026 partisini birleştiren 12 güvenlik açığıdır
  • Üretimde upstream rsync çalıştırıyorsanız 3.4.3 veya üstüne yükseltmelisiniz; gokrazy/rsync içinse v0.3.3 veya üstüne geçilmelidir
  • gokrazy/rsync, Linux dağıtım araştırma projesi distri yazılım paketlerini router7 üzerinden sunmak için yazıldı; router7 ise Go appliance platformu gokrazy tabanlıdır
  • Başlangıçta yalnızca bir rsync sunucusu vardı, ancak artık tüm yönleri destekliyor ve Go programlarına bağlanabilen temel rsync işlevi olarak birden fazla gokrazy/rsync sunucusunda kullanılıyor

Ocak 2025 güvenlik açıkları

  • CVE-2024-12084: Heap buffer overflow, önem derecesi 9.8

    • rsync, ağdan alınan sağlama toplamı uzunluğunu MAX_DIGEST_LEN ile karşılaştırıyordu, ancak iç veri yapısı her zaman 16 baytlık char sum2[SUM_LENGTH] tamponunu kullanıyordu
    • MAX_DIGEST_LEN, SHA256 veya SHA512 sağlama toplamı desteğiyle derlendiğinde daha büyük olabildiği için saldırgan sum2 tampon sınırını en fazla 48 bayt aşacak şekilde yazabiliyordu
    • Sorun, SHA256/SHA512 sağlama toplamı desteğini ekleyen Eylül 2022 tarihli commit ae16850 ile ortaya çıktı
    • upstream düzeltmesi, sum2 yerine dinamik olarak ayrılan sum2_array kullanıyor ve ayırma/doğrulamayı aktarım algoritmasının sağlama toplamı uzunluğu olan xfer_sum_len üzerinden yapıyor
    • Go'da hatalı sınır denetimi heap buffer overflow'a yol açmaz; çalışma zamanı sınır kontrolü bir panic üretir
    • gokrazy/rsync'te de sum header doğrulaması eksikti, ancak bu bir boyut karışıklığı değildi; ChecksumLength 512 olarak değiştirilirse Go çalışma zamanı panic: runtime error: slice bounds out of range [:512] with length 16 hatasını üretir
    • Sunucunun tamamen çökmesi arzu edilen bir başarısızlık modu olmadığından, eksik sınır denetimi eklenerek panic error'a dönüştürüldü
  • CVE-2024-12085: Stack bilgi sızıntısıyla ASLR atlatma, önem derecesi 7.5

    • CVE-2024-12084'tekiyle aynı doğrulama eksiği nedeniyle saldırgan, kısa bir sağlama toplamı algoritması seçip ardından daha uzun bir sağlama toplamı gönderdiğini iddia edebiliyordu
    • Google Security raporuna göre heap buffer overflow ile bilgi sızıntısı birleştiğinde, yalnızca anonim okuma erişimine sahip bir istemci rsync sunucu makinesinde keyfi kod çalıştırabiliyordu
    • hash_search(), stack üzerindeki char sum2[MAX_DIGEST_LEN] içinde parça digest'ini oluşturup memcmp() ile karşılaştırıyordu, ancak yerel sum2 stack tamponu başlatılmadığı için artakalan baytlar stack içeriğini taşıyabiliyordu
    • Kötü niyetli istemci, her dosya indirmede 1 bayt sızdırabiliyordu; sızan veriler arasında heap nesne işaretçileri, stack cookie, yerel değişkenler, global değişken işaretçileri ve return pointer bulunabiliyordu
    • “Some checksum buffer fixes”, saldırgan kontrollü s->s2length değerinin aktarım sağlama toplamı uzunluğundan büyük olmasını engelledi; “prevent information leak off the stack” ise sum2 belleğini 0 ile başlatıyor
    • Go, tüm değişkenleri zero value ile başlattığı için bu açıktan etkilenmez; ayrıca gokrazy/rsync, MD4 dışı sağlama toplamı seçiminin eklendiği protokol sürümü 30'u değil protokol sürümü 27'yi uygular
  • CVE-2024-12087: Sembolik bağlantı kullanarak dizin geçişi, önem derecesi 7.5

    • Google Security raporuna göre, -l veya -a(--archive) ile sembolik bağlantı senkronizasyonu etkin olduğunda kötü niyetli bir sunucu istemciye hedef dizin dışındaki keyfi dosyalara yazdırabiliyordu
    • Saldırı, --inc-recursive modunda birden fazla dosya listesi gönderip ilk listede symlink öğesini dizin olarak tanımladıktan sonra, sonraki listede aynı adı hedef dizin dışını gösteren bir sembolik bağlantıya çevirmekle yapılıyordu
    • Go tek başına bu açığı engelleyemez; neden, birden fazla dosya listesini birleştirdikten sonra yeniden doğrulama yapılmayan mantık hatasıdır
    • upstream düzeltmesi, eksik doğrulamayı ekliyor
    • gokrazy/rsync, incremental recursion modunu (--inc-recursive) uygulamadığı için etkilenmiyor
    • incremental recursion, aktarım başlamadan önce tüm dosya kümesini tamamen taramak yerine “windowed” biçimde işlemeyi sağlar, ancak bunun uygulama karmaşıklığı ile kaynak kullanımı arasında bir trade-off'u vardır
  • CVE-2024-12088: --safe-links atlatması, önem derecesi 7.5

    • Google Security raporuna göre --safe-links, sunucudan alınan sembolik bağlantıların hedef dizinin içini gösterdiğini doğrulayan bir özelliktir
    • Atlatma, sembolik bağlantı hedef yolunun ortasında başka bir sembolik bağlantı bulunup bulunmadığını hesaba katmamasından kaynaklanıyordu
    • Örneğin {DESTINATION}/a -> . ve {DESTINATION}/foo -> a/a/a/a/a/a/../../ varsa foo gerçekte hedef dizinin dışını gösterir, ancak unsafe_symlink() a/ yolunu dizin varsayarak bunu güvenli kabul eder
    • upstream düzeltmesi, yolun başlangıcı dışındaki konumlarda ../ kullanımına izin vermeyerek unsafe_symlink() işlevini daha katı hale getiriyor
    • Go tek başına hatalı bir doğrulama işlevini engelleyemez; gokrazy/rsync ise henüz --safe-links özelliğini uygulamadığı için savunmasız değildir
  • CVE-2024-12086: Keyfi dosya sızıntısı, önem derecesi 6.8

    • rsync receiver, istemci modunda rsync sender'ın sağladığı dosya adlarını temizlemiyor ve hedef ağacının dışındaki dosyaların açılmasını engelleyemiyordu
    • Kötü niyetli sender, receiver'a hedef ağacının dışındaki keyfi bir dosyanın sağlama toplamlarını karşılaştırmasını söyleyebiliyor ve 1 baytlık sağlama toplamına receiver'ın verdiği tepkiyi gözlemleyerek keyfi dosyaları sızdırabiliyordu
    • Google Security raporuna göre istemci kötü niyetli bir sunucuya bağlanırsa sunucu, istemci makinesindeki keyfi dosyaların içeriğini sızdırabiliyordu
    • upstream düzeltmesi, sender tarafından sağlanan yolları doğrulayarak hedef ağacının dışındaki dosyaların açılmasını önlüyor
    • Go'da bunu engelleyebilecek API'ler vardır; ilgili savunma olarak Go'nun os.Root özelliği örnek gösteriliyor
    • gokrazy/rsync, fuzzy matching özelliğinin eklendiği protokol sürümü 29'u değil protokol sürümü 27'yi uyguladığı için savunmasız değildir
  • CVE-2024-12747: Sembolik bağlantı yarış durumu, önem derecesi 5.6

    • Red Hat Security Advisory'e göre bu, rsync'in sembolik bağlantı işleme sürecindeki yarış durumundan kaynaklanan bir kusurdu
    • rsync'in varsayılan davranışı sembolik bağlantıyla karşılaşınca onu atlamaktır, ancak saldırgan uygun anda normal bir dosyayı sembolik bağlantıya çevirerek bu varsayılan davranışı atlatıp sembolik bağlantının takip edilmesini sağlayabiliyordu
  • upstream düzeltmesi, rsync göndericisindeki open() çağrısının O_NOFOLLOW seçeneğini kullanacak şekilde değiştirildi

    • gokrazy/rsync, commit 1b1fbf6 öncesine kadar etkileniyordu; bu commit, upstream rsync ile aynı O_NOFOLLOW azaltımını getirdi
    • Damien Neil, gokrazy'nin CVE-2024-12747 düzeltmesinin yetersiz olduğunu düşündü ve O_NOFOLLOW'un yalnızca son yol bileşenindeki sembolik bağlantı takibini engellediği sonucuna vardı
    • Örneğin os.Open("dir/passwd") durumunda, önceki yol bileşeni olan dir /etc'ye işaret eden bir sembolik bağlantıyla değiştirilirse yine de atlatılabilir
    • Bu sorun Nisan 2025'te rsync güvenlik irtibatına bildirildi ve 2026-05-20 tarihinde açıklanan CVE-2026-29518 ile sonuçlandı

Mayıs 2026 güvenlik açıkları

  • CVE-2026-29518: Sembolik bağlantı yarış durumu, önem derecesi 7.0

    • rsync 3.4.3 NEWS girdisi'ne göre, chroot olmadan daemon mode'da yerel yetki yükseltmeye izin veren bir TOCTOU sembolik bağlantı yarış durumudur
    • use chroot = no olarak yapılandırılmış rsync daemon, üst yol bileşenleri üzerinde time-of-check/time-of-use yarışına maruz kalır
    • Modüle yazma erişimi olan yerel bir saldırgan, receiver'ın denetimi ile open() çağrısı arasına girerek üst dizin bileşenini sembolik bağlantıyla değiştirebilir; bu da okumalarda basis-file ifşasına, yazmalarda ise modül dışındaki dosyaların üzerine yazılmasına yol açabilir
    • Varsayılan olan use chroot = yes etkilenmez
    • upstream düzeltmesi, Go'nun os.Root API'sine benzer secure_relative_open() kullanır
    • gokrazy/rsync, sender ve receiver tarafını dolaşıma dayanıklı os.Root API'sine geçirene kadar savunmasızdı
  • CVE-2026-43618: Tamsayı taşmasıyla uzaktan bellek sızıntısı, önem derecesi 8.1

    • rsync receiver'ının sıkıştırma belirteci kod çözücüsü, 32 bit işaretli sayaçları taşma kontrolü olmadan biriktirerek kötü niyetli bir sender'ın süreç belleği içeriğini sızdırmasına olanak tanır
    • Sızabilecek veriler arasında ortam değişkenleri, parolalar, heap ve kütüphane işaretçileri yer alabilir; bu da ASLR'yi zayıflatıp ek istismarları kolaylaştırabilir
    • Etki alanı, sıkıştırmanın etkin olduğu kimliği doğrulanmış daemon bağlantılarıyla sınırlıdır ve protokol 30 ve sonrasında her iki peer de sıkıştırma ilan ederse varsayılan olarak etkinleşir
    • Geçici çözüm, rsyncd.conf içinde refuse options = compress ile daemon sıkıştırmasını devre dışı bırakmaktır
    • upstream düzeltmesi, eksik denetimleri ekler
    • gokrazy/rsync, sıkıştırma uygulamadığı için savunmasız değildir; sıkıştırma desteği basit görünse de neden önemsiz olmadığı gokrazy/rsync issue #35 içinde özetlenmiştir
  • CVE-2026-43620: Sınır dışı okuma sonrası hizmet reddi, önem derecesi 6.5

    • 2025'te send_files() içine eklenen parent_ndx<0 koruması, görsel olarak aynı olan recv_files() bloğuna uygulanmadığı için ortaya çıkmıştır
    • Kötü niyetli bir rsync sunucusu CF_INC_RECURSE uyumluluk bayrağı ve hatalı oluşturulmuş bir flist gönderirse, receiver dir_flist->files[-1] değerini okuyup referansını çözebilir ve bu da deterministik bir SIGSEGV ile sonuçlanabilir
    • Etkilenenler, saldırganın kontrol ettiği URL'lerden normal pull işlemi yapan tüm rsync istemcileridir; çünkü protokol 30 ve sonrasında varsayılan olan inc_recurse nedeniyle kurban tarafında özel bir seçenek gerekmez
    • İstemcide --no-inc-recursive kullanmak geçici çözümdür ve upstream düzeltmesi, recv_files() içine de parent_ndx<0 korumasını ekler
    • gokrazy/rsync, --inc-recursive artımlı özyinelemeli modu uygulamadığı için CVE-2024-12087'de olduğu gibi etkilenmez
  • CVE-2026-43619: Ek sembolik bağlantı yarış durumu, önem derecesi 6.3

    • Receiver'ın open() çağrısındaki sembolik bağlantı yarış durumu düzeltmesi (CVE-2026-29518), chmod, lchown, utimes, rename, unlink, mkdir, symlink, mknod, link, rmdir, lstat gibi diğer yol tabanlı sistem çağrılarına uygulanmamıştı
    • use chroot = no olarak yapılandırılmış rsync daemon'da yerel bir saldırgan, receiver'ın kontrolü ile sistem çağrısı arasına girip üst dizin bileşenini sembolik bağlantıyla değiştirerek işlemi dışa aktarılan modülün dışına yönlendirebilir
    • Varsayılan olan use chroot = yes etkilenmez
    • upstream düzeltmesi, Linux 5.6+ üzerindeki openat2, FreeBSD 13+ ve macOS 15+ üzerindeki O_RESOLVE_BENEATH ve diğer ortamlarda bileşen bazlı O_NOFOLLOW dolaşımı gibi çekirdek tarafından zorlanan kısıtlamalar altında açılmış bir üst dirfd üzerinden etkilenen yol tabanlı sistem çağrılarını işler
    • gokrazy/rsync, Go'nun os.Root API'sini genel olarak kullandığı için etkilenmez
  • CVE-2026-43617: Ana makine adına dayalı ACL atlatma, önem derecesi 4.8

    • Genel daemon chroot = /X rsyncd.conf ayarına sahip rsync daemon'da, bağlanan istemcinin ters DNS sorgusu daemon /X içine chroot olduktan sonra yapılıyordu
    • /X içinde glibc çözümlemesi için gereken /etc/resolv.conf, /etc/nsswitch.conf, /etc/hosts ve NSS hizmet modülleri yoksa sorgu başarısız olur ve bağlanan ana makine adı "UNKNOWN" olarak ayarlanır
    • hosts deny = *.evil.example gibi ana makine adına dayalı deny kuralları eşleşmez; böylece PTR kaydını kontrol eden bir saldırgan, yöneticinin engellemek istediği bir ana makine adından bağlanabilir
    • IP tabanlı ACL'ler etkilenmez ve modül başına use chroot ayarı bu güvenlik açığıyla ilgili değildir
    • upstream düzeltmesi, DNS sorgusunu protokolün daha erken bir aşamasına taşır
    • gokrazy/rsync, ana makine adına dayalı allow/deny listelerini uygulamaz ve yalnızca IP tabanlı allow/deny listeleri uygular; bu yüzden savunmasız değildir
  • CVE-2026-45232: Yığın sınırı dışı yazma, önem derecesi 3.1

    • rsync istemcisinin HTTP CONNECT proxy desteğinde establish_proxy_connection() içinde off-by-one bir yığın sınırı dışı yazma hatası bulunur
    • Bir proxy veya ortadaki adam saldırganı ilk yanıt satırında '\n' olmadan 1023 bayt veya daha fazlasını döndürürse, devamındaki kod 1024 baytlık tamponun hemen sonrasına '\0' yazarak bitişik yığın yuvasını bozabilir
    • AddressSanitizer, establish_proxy_connection çerçevesinde socket.c:95 konumunda stack-buffer-overflow bildirir
    • upstream düzeltmesi, saldırganın sağladığı veriyi doğrular
    • gokrazy/rsync, bu tür proxy desteğini uygulamadığı için savunmasız değildir

Go ve gokrazy/rsync’in gerçekten engelledikleri

  • Go çalışma zamanının sınır denetimleri, daha ciddi güvenlik sorunlarını panic’e dönüştürüyor; panic hâlâ bir hizmet reddi riski olsa da daha iyi bir başarısızlık modu olarak değerlendiriliyor
  • Go belleği 0 ile başlattığı için CVE-2024-12085 gibi bilgi sızıntılarını imkânsız hâle getiriyor
  • Go’nun os.Root API’si kalan açıkların çoğunu önlüyor
  • 12 açıktan yalnızca biri, CVE-2026-43617, Go kullanımıyla engellenemeyen bir uygulama mantığı hatası olarak sınıflandırılıyor
  • gokrazy/rsync ile resmi upstream rsync arasındaki temel fark, Go ile yazılmış olmasının yanı sıra, uygulamanın minimal tutulmuş olması
  • gokrazy/rsync, --inc-recursive, --safe-links, sıkıştırma, proxy ve ana makine adı ACL’leri gibi sorunlu birçok özelliği uygulamadığı için çeşitli açıkları da önlüyor
  • Tüm wire protocol uyumlu rsync uygulamaları gibi gokrazy/rsync de protokol sürüm 27’yi hedefliyor; sonraki protokol sürümleri kayda değer ölçüde karmaşıklık getiriyor
  • Yayın anı itibarıyla CVE bazında gokrazy/rsync durumu:
    • 2024-12084: uygulama mevcuttu ve panic oluşuyordu
    • 2024-12085: protokol 30 özelliği olduğu için uygulanmadı, bu yüzden etkilenmiyor
    • 2024-12086: protokol 29 özelliği olduğu için uygulanmadı, bu yüzden etkilenmiyor
    • 2024-12087: inc-rec uygulanmadığı için etkilenmiyor
    • 2024-12088: safe-links uygulanmadığı için etkilenmiyor
    • 2024-12747: uygulama mevcuttu ve etkileniyordu
    • 2026-29518: uygulama mevcuttu ve yamalandı
    • 2026-43617: host deny listesi uygulanmadığı için etkilenmiyor
    • 2026-43618: sıkıştırma uygulanmadığı için etkilenmiyor
    • 2026-43619: uygulama mevcuttu ve yamalandı
    • 2026-43620: inc-rec uygulanmadığı için etkilenmiyor
    • 2026-45232: proxy uygulanmadığı için etkilenmiyor
  • gokrazy/rsync’te bilinen tüm açıklar giderildi; yukarıdaki durum, her CVE’nin açıklandığı andaki durumu gösteriyor
  • Ocak 2025’te açıklar duyurulduğunda gokrazy/rsync, CVE-2024-12084’te panic üretiyor ve CVE-2024-12747 TOCTOU yarış durumundan etkileniyordu
  • TOCTOU sorunu düzeltilirken CVE-2026-29518 keşfedildi ve bu CVE kamuya açıklanmadan önce gokrazy/rsync’te düzeltildi
  • CVE-2026-43619 daha sonra keşfedildi, ancak Go’nun os.Root kullanımına tamamen geçilmesi şeklindeki aynı düzeltme sayesinde gokrazy/rsync’te zaten çözülmüş durumdaydı

Rol ayrımı ve açıkların adlandırılması

  • Birçok açık raporunda “server” ve “client” ifadeleri kullanılsa da rsync aktarımında hem rsync istemcisi hem de sunucusu gönderici (sender, dosya yükleme) veya alıcı (receiver, dosya indirme) rolünü üstlenebilir
  • Daemon modunda dosya sistemi erişimi önceden yapılandırılmış modül yollarıyla sınırlandırılabilir, ancak command mode’da bu mümkün değildir
  • Dört yapılandırma ile rol/protokol katmanları rsync combinations diyagramında görülebilir
  • Arbitrary File Leak açığının (CVE-2024-12086) özgün başlığı olan “Server leaks arbitrary client files”, yanlış anlamaya açıktır
  • Daha doğru ifade, rsync alıcısının kötü niyetli bir göndericiye keyfi dosyaları sızdırmasıdır
  • Kötü niyetli bir istemci göndericisi, SSH üzerinden command mode gibi ortamlarda yamasız bir uzak rsync’i hedef ağacın dışındaki dosyaları, örneğin /etc/shadow sistem parola veritabanını, açmaya zorlayabilir
  • Daemon modunda sunucu, ek yol normalleştirmeyi (path sanitization) etkinleştirerek bu saldırıyı engeller
  • Symlink Path Traversal açığı (CVE-2024-12087) da “malicious server” olarak tanımlanır, ancak doğrusu bunun istemci ya da sunucu olabilen kötü niyetli bir gönderici olduğudur

OpenBSD openrsync ile karşılaştırma

  • OpenBSD projesi güvenliğe odaklanmasıyla bilinir; openrsync checksum uzunluğunu doğrular ve checksum boyutu/algoritması olarak yalnızca MD4’ü destekler, bu nedenle Heap Buffer Overflow (CVE-2024-12084) ve Stack Info Leak (CVE-2024-12085) açıklarından etkilenmez
  • openrsync de gokrazy/rsync gibi ilgili özellikleri uygulamadığı için CVE-2024-12086, CVE-2024-12087 ve CVE-2024-12088’den etkilenmez
  • Etkilense bile OpenBSD üzerinde çalışırken OpenBSD unveil(2) ve pledge(2) ile dosya sistemi erişimini kısıtlayan savunma derinliği başarılı istismarı engellemiş olabilir
  • openrsync, sembolik bağlantı desteğini uyguladığı andan itibaren O_NOFOLLOW kullanıyor; bu nedenle CVE-2024-12747’den etkilenmiyor
  • Ancak O_NOFOLLOW bu sorun için yeterli bir düzeltme olmadığından openrsync CVE-2026-29518’den etkileniyor
  • Mayıs 2026 paketindeki durum da büyük ölçüde benzer; çünkü ilgili özelliklerin çoğu yine uygulanmamıştı
  • openrsync, doğrulamayı özenle uygulayıp saldırı yüzeyini sınırlayarak ve savunma derinliği kullanarak bildirilen açıkların çoğundan etkilenmiyor

Derinlemesine savunma ve os.Root

  • Linux mount namespace

    • gokrazy/rsync projesinin başlamasından birkaç hafta sonra, dosya sistemi nesnelerine erişimi sınırlamak için Linux'ta yetki düşürme ve mount/pid namespace kullanımını destekleyen bir özellik eklendi
    • Bu yaklaşım path traversal saldırılarını hafifletmede iyi çalışıyor, ancak ayrıcalık gerektiriyor; bu yüzden root olarak çalıştırılması ya da dağıtım/sistemde etkinse Linux user namespace içinde çalıştırılması gerekiyor
    • mount namespace sunucu yapılandırmaları için uygun, ancak sıradan kullanıcı hesabıyla çalıştırılan etkileşimli tek seferlik aktarımlarda çoğu zaman kullanılamıyor
  • systemd sertleştirmesi

    • Linux mount/pid namespace desteğini getiren aynı commit, dosya sistemi erişimini home diziniyle sınırlayan bir systemd servis dosyasını da içeriyordu ve README'de kullanım durumuna göre dosya sistemi erişiminin daha da kısıtlanması öneriliyor
    • Bu tür dosya sistemi kısıtlamaları doğru yapılandırıldığında File Leak (CVE-2024-12086) ve Path Traversal (CVE-2024-12087) açıklarını hafifletiyor
    • Symlink Race Condition (CVE-2024-12747), rsync süreci üzerinden yetki yükseltmeye dayanıyor, ancak DynamicUser özelliği sayesinde süreç diğer kullanıcılardan daha az ayrıcalığa sahip oluyor
    • mount namespace gibi bu da sunucu yapılandırmaları için iyi, ancak etkileşimli tek seferlik kullanım için ayarlaması zahmetli
  • Linux Landlock

    • Porting OpenBSD pledge() to Linux (2022) sayesinde, Linux'ta da OpenBSD'nin unveil(2)'ine benzer, ayrıcalık gerektirmeyen ve süreç başına çalışan erişim kontrolü olan Landlock API bulunduğu yeniden hatırlandı
    • Temel fikir, program çalışacağı dizinleri öğrendikten sonra unveil("/home/michael/backups", "rw"); gibi bir çağrıyla bu yol dışındaki dosya sistemi konumlarına artık erişememesidir
    • 2025 Mart'ında dosya sistemi erişimini sınırlamak için Landlock desteği uygulandı
    • Ayarlar yapıldıktan sonra, ayrıcalıksız gokrazy/rsync çalıştırmalarında bile rsync aktarımı kaynak için salt okunur, hedef dizin içinse okuma-yazma ile sınırlandırılabiliyor
    • Dezavantajı, Landlock'un süreç düzeyinde çalışması
    • Landlock politikasına programın ihtiyaç duyduğu dosyalar da dahil edilmeli; örneğin gokrazy/rsync kullanıcı kimliği sorgulamak için /etc/passwd dosyasını okuyabilmeli, dolayısıyla saldırgan /etc/passwdyi hedefliyorsa Landlock yardımcı olmuyor
  • Go'nun os.Root'u

    • 2025 Şubat'ında Go 1.24, path traversal'a dayanıklı os.Root API'sini tanıttı; bunun arka planı Damien Neil'in The Go Blog: Traversal-resistant file APIs yazısında özetleniyor
    • os.Root, Landlock ile karşılaştırıldığında dosya sistemi işlemi bazında daha ince taneli denetim sağlıyor
    • 2025 Ağustos'unda yayımlanan Go 1.25, os.Root'a daha fazla yöntem ekleyerek onu çoğu dosya sistemi kullanımı için pratik bir seçenek haline getirdi
    • gokrazy/rsync içindeki tüm dosya sistemi kullanımı os.Root'a geçirildi ve bu, kullanıcının giriş/çıkış dizinlerini yapılandırdığı ama ağ üzerinden gelen dosya adlarının güvenilmez olduğu modele çok iyi uyuyor
    • mknod(2) gibi API ile doğrudan oluşturulamayacak gibi görünen sistem çağrıları bile güvenli biçimde kullanılabiliyor
    • Damien Neil, os.Root.OpenFile ile hedefin üst dizininin açılabileceğini, File.Fd ile o dizinin dosya tanımlayıcısının alınabileceğini ve ardından golang.org/x/sys/unix#Mknodat ile dosyanın oluşturulabileceğini açıklıyor
    • Gerçek kullanım örneği internal/receiver/generatormknod_linux.go, line 15-29 içinde görülebilir
    • Linux'ta mknodat(2) var, ancak Linux 7.0 itibarıyla bind(2) karşılığı bir bindat yok
    • Lennart Poettering, bindat olmadan yol çözümlemeyi atlamanın bir hilesi olarak /proc/self/<fd>/foobar üzerine bind edilebileceğini öne sürüyor
    • Bilinen güvenli /proc/self/<fd> sonrasına bir yol değil, bir basename yani son yol bileşeni verilirse yol çözümleme atlanıyor; ilgili kod line 49-56 içinde yer alıyor
    • Bu iki ipucuyla gokrazy/rsync v0.3.1 ve sonrasında os.Root tamamen kullanılıyor ve tüm dosya sistemi erişimleri path traversal güvenliği kazanıyor

Temel dersler

  • TOCTOU açıkları (CVE-2024-12747, CVE-2026-29518, CVE-2026-43619) dışındaki tüm açıklar, eksik girdi doğrulamasından veya hatalı girdi doğrulamasından kaynaklanıyor
  • Üç durumda baştan hiç doğrulama yoktu; CVE-2024-12088'de ise dosya sistemi yol çözümleme konusu zor olduğu için mevcut doğrulama tüm sınır durumlarını kapsayamıyordu
  • En değerli yapısal düzeltme, sınır kontrolü gibi her zaman açık doğrulamalar ve Go'nun os.Rootu gibi varsayılan olarak güvenli API'ler sunmaktır
  • Bazı açıklar rsync protokolünün evriminden doğdu; başlangıçta yeterli doğrulama yapan koda yeni özellikler eklendiğinde doğrulama doğru şekilde güncellenmedi
  • Checksum algoritması anlaşması ve artımlı özyineleme protokol sürümü 30'da eklendi ve mevcut doğrulama yeni özelliklerin işlenişine uygun şekilde güncellenmedi
  • gokrazy/rsync ve openrsync, savunmasız özellikleri uygulamadıkları için 12 güvenlik açığının 8'ine karşı savunmasız değildi
  • Bu özellikler bir noktada birileri için değerli olduğu için rsync'e eklendi; bu, yazılım geliştirmeyi durdurmak gerektiği anlamına gelmiyor
  • İdeal tercih, kullanım durumunun karmaşıklığına uygun ve onunla orantılı karmaşıklıkta bir uygulama kullanmaktır; basit kullanım durumları için basit uygulamalar seçilmeli, tam özellikli uygulamalar ise yalnızca gerektiğinde tercih edilmelidir

1 yorum

 
GN⁺ 2 시간 전
Lobste.rs görüşleri
  • Harika bir yazı. Tüm dillerin standart kütüphanesine os.Root benzeri API'ler koyması gerekecek kadar iyi
    SecureDrop'ta birkaç yol geçişi zafiyeti yaşadıktan sonra bunun çok basitleştirilmiş bir sürümünü kullandım; artık doğru API'yi kullanınca bir zafiyet sınıfı tamamen ortadan kalkıyor
    • Aynen. Bu blog yazısının asıl yıldızı Go'dan çok os.Root gibi görünüyor