Minimal bellek güvenli Go rsync’im güvenlik açıklarından nasıl kaçınıyor
(michael.stapelberg.ch)- 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_LENile karşılaştırıyordu, ancak iç veri yapısı her zaman 16 baytlıkchar 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ırgansum2tampon 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
ae16850ile ortaya çıktı - upstream düzeltmesi,
sum2yerine dinamik olarak ayrılansum2_arraykullanıyor ve ayırma/doğrulamayı aktarım algoritmasının sağlama toplamı uzunluğu olanxfer_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;
ChecksumLength512olarak değiştirilirse Go çalışma zamanıpanic: runtime error: slice bounds out of range [:512] with length 16hatası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ü
- rsync, ağdan alınan sağlama toplamı uzunluğunu
-
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 üzerindekichar sum2[MAX_DIGEST_LEN]içinde parça digest'ini oluşturupmemcmp()ile karşılaştırıyordu, ancak yerelsum2stack 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->s2lengthdeğerinin aktarım sağlama toplamı uzunluğundan büyük olmasını engelledi; “prevent information leak off the stack” isesum2belleğ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,
-lveya-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-recursivemodunda birden fazla dosya listesi gönderip ilk listedesymlinköğ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
- Google Security raporuna göre,
-
CVE-2024-12088:
--safe-linksatlatması, ö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/../../varsafoogerçekte hedef dizinin dışını gösterir, ancakunsafe_symlink()a/yolunu dizin varsayarak bunu güvenli kabul eder - upstream düzeltmesi, yolun başlangıcı dışındaki konumlarda
../kullanımına izin vermeyerekunsafe_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
- Google Security raporuna göre
-
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ınO_NOFOLLOWseçeneğini kullanacak şekilde değiştirildi- gokrazy/rsync, commit
1b1fbf6öncesine kadar etkileniyordu; bu commit, upstream rsync ile aynıO_NOFOLLOWazaltı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 olandir/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ı
- gokrazy/rsync, commit
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 = noolarak 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 = yesetkilenmez - upstream düzeltmesi, Go'nun
os.RootAPI'sine benzersecure_relative_open()kullanır - gokrazy/rsync, sender ve receiver tarafını dolaşıma dayanıklı
os.RootAPI'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 = compressile 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 eklenenparent_ndx<0koruması, görsel olarak aynı olanrecv_files()bloğuna uygulanmadığı için ortaya çıkmıştır - Kötü niyetli bir rsync sunucusu
CF_INC_RECURSEuyumluluk bayrağı ve hatalı oluşturulmuş bir flist gönderirse, receiverdir_flist->files[-1]değerini okuyup referansını çözebilir ve bu da deterministik birSIGSEGVile 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_recursenedeniyle kurban tarafında özel bir seçenek gerekmez - İstemcide
--no-inc-recursivekullanmak geçici çözümdür ve upstream düzeltmesi,recv_files()içine deparent_ndx<0korumasını ekler - gokrazy/rsync,
--inc-recursiveartımlı özyinelemeli modu uygulamadığı için CVE-2024-12087'de olduğu gibi etkilenmez
- 2025'te
-
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,lstatgibi diğer yol tabanlı sistem çağrılarına uygulanmamıştı use chroot = noolarak 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 = yesetkilenmez - upstream düzeltmesi, Linux 5.6+ üzerindeki
openat2, FreeBSD 13+ ve macOS 15+ üzerindekiO_RESOLVE_BENEATHve diğer ortamlarda bileşen bazlıO_NOFOLLOWdolaşımı gibi çekirdek tarafından zorlanan kısıtlamalar altında açılmış bir üstdirfdüzerinden etkilenen yol tabanlı sistem çağrılarını işler - gokrazy/rsync, Go'nun
os.RootAPI'sini genel olarak kullandığı için etkilenmez
- Receiver'ın
-
CVE-2026-43617: Ana makine adına dayalı ACL atlatma, önem derecesi 4.8
- Genel
daemon chroot = /Xrsyncd.conf ayarına sahip rsync daemon'da, bağlanan istemcinin ters DNS sorgusu daemon/Xiçine chroot olduktan sonra yapılıyordu /Xiçinde glibc çözümlemesi için gereken/etc/resolv.conf,/etc/nsswitch.conf,/etc/hostsve NSS hizmet modülleri yoksa sorgu başarısız olur ve bağlanan ana makine adı"UNKNOWN"olarak ayarlanırhosts deny = *.evil.examplegibi 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 chrootayarı 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
- Genel
-
CVE-2026-45232: Yığın sınırı dışı yazma, önem derecesi 3.1
- rsync istemcisinin HTTP
CONNECTproxy desteğindeestablish_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çevesindesocket.c:95konumundastack-buffer-overflowbildirir - 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
- rsync istemcisinin HTTP
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.RootAPI’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şuyordu2024-12085: protokol 30 özelliği olduğu için uygulanmadı, bu yüzden etkilenmiyor2024-12086: protokol 29 özelliği olduğu için uygulanmadı, bu yüzden etkilenmiyor2024-12087:inc-recuygulanmadığı için etkilenmiyor2024-12088:safe-linksuygulanmadığı için etkilenmiyor2024-12747: uygulama mevcuttu ve etkileniyordu2026-29518: uygulama mevcuttu ve yamalandı2026-43617: host deny listesi uygulanmadığı için etkilenmiyor2026-43618: sıkıştırma uygulanmadığı için etkilenmiyor2026-43619: uygulama mevcuttu ve yamalandı2026-43620:inc-recuygulanmadığı için etkilenmiyor2026-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.Rootkullanı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/shadowsistem 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)vepledge(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_NOFOLLOWkullanıyor; bu nedenle CVE-2024-12747’den etkilenmiyor - Ancak
O_NOFOLLOWbu 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
rootolarak ç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/rsynckullanıcı kimliği sorgulamak için/etc/passwddosyasını okuyabilmeli, dolayısıyla saldırgan/etc/passwdyi hedefliyorsa Landlock yardımcı olmuyor
- Porting OpenBSD pledge() to Linux (2022) sayesinde, Linux'ta da OpenBSD'nin
-
Go'nun os.Root'u
- 2025 Şubat'ında Go 1.24, path traversal'a dayanıklı
os.RootAPI'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/rsynciç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 uyuyormknod(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.OpenFileile hedefin üst dizininin açılabileceğini,File.Fdile o dizinin dosya tanımlayıcısının alınabileceğini ve ardındangolang.org/x/sys/unix#Mknodatile 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ıylabind(2)karşılığı birbindatyok - Lennart Poettering,
bindatolmadan 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/rsyncv0.3.1 ve sonrasındaos.Roottamamen kullanılıyor ve tüm dosya sistemi erişimleri path traversal güvenliği kazanıyor
- 2025 Şubat'ında Go 1.24, path traversal'a dayanıklı
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
Lobste.rs görüşleri
os.Rootbenzeri API'ler koyması gerekecek kadar iyiSecureDrop'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
os.Rootgibi görünüyor