1 puan yazan GN⁺ 2023-07-04 | 1 yorum | WhatsApp'ta paylaş
  • 2004'ten bu yana baskın pazar payına sahip çok amaçlı web sunucusu Nginx
  • Nginx'in yanlış yapılandırılması güvenlik açıklarına ve veri ifşasına yol açabilir
  • Nginx'teki açıkları tespit etmeye yönelik otomasyon aracı NavGix tanıtılıyor
  • Bu açık, amaçlananın dışındaki dosya ve dizin kapsamına erişim sağlayabilir
  • Bitwarden ve Google'ın HPC Toolkit'i üzerine vaka çalışmaları, bu açığın ciddiyetini gösteriyor

1 yorum

 
GN⁺ 2023-07-04
Hacker News yorumları
  • Bilginize, gixy (nginx yapılandırma denetleyicisi) bu sorunu yakalıyor: https://github.com/yandex/gixy/blob/master/docs/en/plugins/a...
    Ayrıca NixOS, kendi üzerinden üretilen yapılandırmalarda gixy’yi otomatik çalıştırıyor ve bir sorun varsa sistem derlemesini reddediyor

    • Eğer bir web sunucusunun, kullanıcıların bu tür tuzaklardan kaçınması için ek araçlara ihtiyaç duyması gerekiyorsa, belki de varsayılanların yeniden gözden geçirilmesi gerekir
    • gixy’yi bilmiyordum; ev sunucumda çalıştırınca bir açık buldu. 301 yönlendirmesi içinde $uri kullanıyormuşum
    • Nix’i biraz denedim ve şu ana kadar oldukça iyi görünüyor
      Ama daha iyi bir seçenek arayıcısı olup olmadığını merak ediyorum. Binlerce seçeneğin tamamında arama yapmak pek iyi gelmedi; ssh gibi yalnızca bir pakete bakıp sadece onunla ilgili seçenekleri görmek istiyorum ama alakasız sonuçlar çok fazla karışıyor
    • NixOS artık Gixy’yi çalıştırmıyor. https://github.com/NixOS/nixpkgs/pull/209075 bağlantısına bakın
  • Aptalca bir soru olabilir ama nginx’in URL yolunda .. ile üst dizine çıkılmasına izin vermesi için iyi bir neden var mı? Bu, sadece sorun bekleyen bir davranış gibi görünüyor
    Düzeltme: Orijinal açıktaki tam olarak ne olduğunu biraz karıştırıyorum. http://localhost/foo../secretfile.txt sanki /var/www/foo/../secretfile.txt olarak yorumlanıyor gibi; ama açık olmayan bir sunucuda neden http://localhost/foo/../secretfile.txt da aynı şekilde yorumlanmıyor? Yoldaki .. neden yalnızca bazı durumlarda çalışıyor, anlayamıyorum

    • Bu, nginx’te çok uzun zamandır bilinen bir sorun ve CTF’lerde yaygın bir saldırı vektörü: https://book.hacktricks.xyz/network-services-pentesting/pent...
    • Sorun, URL’nin gerçek bir yol olmaması. URL; dizin, dosya, çalıştırılabilir dosya, akış vb. olabilen bir kaynağın soyut adresidir
      Bu durumda URL’nin bir kısmı, yapılandırmada yerel dosya sistemine eşlenme biçimi nedeniyle nginx tarafından bir dizin olarak yorumlanıyor (http://localhost/foo). Dizin gösteriyor gibi göründüğü için nginx, istenen kaynağın tam yolunu oluştururken "${mapped_path}/../secretfile.txt" elde ediyor; bu URL açısından anlamsız olsa da yerel dosya sistemi açısından geçerli hale geliyor. URL’ler gerçek yol öğeleri değil, yalnızca dizgelerdir; bu yüzden eğik çizginin yeri de özünde önemli değildir
      Web ortaya çıktığından beri, bu web sunucularında çok sık görülen bir sorun. URL’leri doğrudan dosya yollarına eşlemek, dizinli basit dosya sunucularıyla başladığı için popülerdi; ama kısa sürede, URL’nin bir yol değil uygulama tanımlayıcısı olduğu karma ortamlara geçildi. Yolun bir kısmıyla uygulama seçilir, geri kalanı da parametre ya da argüman gibi ele alınır
      Ve genel olarak, dosya sistemi nesneleri için URL içindeki . ya da .. öğelerine saygı göstermek çoğu zaman mantıklı değildir. Benim uygulamalarım, doğru eşleme için istek yolunu temizler. Tarayıcılar göreli bağlantılar oluştururken URL’yi yol gibi ele aldığından, sondaki / işaretini ne zaman ve nasıl kullandığınıza da dikkat etmeniz gerekir. Sunucu tarafında anlamı farklı olan bir kaynağa işaret edebilir
    • “Normal” kullanım durumlarında buna gerek yok. location içinde allow_parent_traversal on; gibi bir bayrak konup açıkça etkinleştirilen bir davranış haline getirilmesi daha doğru görünüyor
    • Tahminimce NginX muhtemelen "/foo/bar/.." ifadesini denetleyip yasaklar ya da "/foo/" biçimine normalleştirir. Ama "/foo/bar.." tamamen geçerli bir dosya adı olduğundan, bu tür bir denetimi atlatıp gözden kaçıyor gibi
    • Yolda .. öğesinin ne zaman çalışacağı tamamen dosya izinlerine bağlıdır
      Bu durumda, web indeks dizininden (../index.html) kök dizine (/) kadar dosya okuma yetkiniz olduğunu varsayalım; köke kadar çıkabildiğiniz için artık kökten erişilebilen tüm world-readable dosyaları, örneğin /etc/passwd dosyasını da görebilirsiniz
      Bunu üç çatallı bir çatal gibi düşünün; web sunucusu en sağdaki dişte duruyor. Dişlerin birleştiği sap kısmı dosya sistemi olsun; web sunucusunun bulunduğu sağ dişten sap kısmına kadar uzanan dosya ve dizinlere erişim izni varsa, sap kısmına ulaştıktan sonra diğer dişlerdeki dosyalara da erişmeye devam edebilir
  • Bunun neden nginx açığı olarak görülmediğini anlayamıyorum. Bu davranış tamamen saçma, faydalı bir amacı da yok gibi ve doğrudan istismar edilebilir

    • Bunun sebebi hız. Basit metin değiştirme, yolun eğik çizgiyle düzgün biçimde bitip bitmediğini kontrol etmekten çok daha hızlı
      Nginx’in, Apache2’den daha fazla “web ölçeğinde” olduğunu gösteren benchmark’lar sayesinde popüler hale geldiğini de hatırlamak gerekir
  • İnsan şöyle bir şey düşünüyor: Linux çekirdeğinin dosya adı ayrıştırıcısına, .. seçeneğini kaldıran Linux capability benzeri bir seçenek koymak.
    Web uygulamalarında, telefon modemlerinin kullanıldığı dönemlerden beri iki noktayı bir şekilde araya sokan çeşitli bypass yöntemleri çıkıp durdu. Linux çekirdeğinin diğer pek çok kullanıcı alanı hata sınıfında yaptığı gibi, artık bu sorunu da tek hamlede kapatmanın bir yolunu bulma zamanı geldi

    • https://man7.org/linux/man-pages/man2/openat2.2.html içindeki RESOLVE_BENEATH var
      FreeBSD'de bu özellik normal openat(2) için O_RESOLVE_BENEATH olarak bulunuyor
    • Bunu yapmak çok fazla şeyi bozardı; aklı başında yapılacak bir iş değil
      nginx'i yetkileri çok kısıtlı ayrı bir kullanıcıyla çalıştırmak ya da Docker içinde çalıştırmak yeterli. Buna düzenli güncellemeleri de ekleyince genelde güvenlik sorunlarının %90'ı çözülür
    • /some/../path neredeyse %100 yasaklanmalı. “Birinin çirkin kod yazmış olması” dışında makul bir kullanım senaryosu yok
      ../some/path ise en azından bazen anlamlı olabilir
      Yine de sanıldığı kadar faydalı olmayabilir. Birçok uygulama işletim sistemine iletmeden önce .. öğesini zaten kendi içinde çözümlüyor
    • Pek fark yaratmaz. Kod, dosya sistemi API'sine ulaşmadan önce çoğu zaman yolu normalize eder
    • Çekirdek tarafında farklı bir mekanizma, yani bizim güvendiğimiz izin sistemi zaten var
      Bir klasörden web'e dosya servis ediyorsanız, web framework'ünün kendisine verilen açık kök klasörün dışına çıkmamasını sağlaması gerekir. Bunu kendiniz yapıyorsanız, buna benzer her türlü durumu hesaba katmanız gerekir
  • “Google VRP Team bu açığı bulan kişiye 500 dolar ödül verdi. Uygulama üzerindeki etkiyi daha yüksek ödülü gerektirecek kadar ciddi görmedi” deniyor; GCP hesap e-postası ve özel anahtarın ifşası sadece 500 dolar mı ediyor? Bu da ne böyle. Tam Google'lık iş

  • Sızan verilerin hâlâ şifreli olması sevindirici. Bu alanda uzmanlaşmış bir şirket bile sızıntıdan kaçamıyorsa, dürüst olmak gerekirse bu neredeyse en iyi senaryo

  • Başlık epeyce değiştirilmiş. Orijinal başlık Hunting for Nginx Alias Traversals in the wild
    HN gönderi başlığı Bitwarden açığını öne çıkarıyor ama yazıda Google örneği de birlikte ele alınıyor

    • Tamam, başlığı geri aldım. Gönderi başlığı “Leaking Bitwarden's Vault with a Nginx vulnerability” idi
  • Kaynak kullanımını en aza indirirken güvenli şekilde yalnızca statik dosya sunumu yapmak gerekiyorsa bugün en iyi seçenek ne olur? Eskiden olsa Nginx seçerdim, ama güvenlik açısından daha dar amaçlı ve daha az yapılandırma ihtimali olan bir araç daha iyi olabilir mi diye merak ediyorum

    • Ben https://static-web-server.net/ kullanıyorum
      Çok platformlu, Rust ile yazılmış, yapılandırması basit ve güvenli varsayılanlara sahip. Güçlendirilmiş container imajı ve güçlendirilmiş NixOS modülü de var
      Caddy'yi önermem. Resmi Docker imajı varsayılan olarak root ile çalışıyor [1] ve düzgün sandbox edilmiş bir systemd unit dosyası da sunmuyor [2]
      [1]: https://github.com/caddyserver/caddy-docker/issues/104
      [2]: https://github.com/caddyserver/dist/blob/master/init/caddy.s...
      Düzenleme: ifade düzeltildi
    • Biraz reklam yapmış olayım, Caddy burada gayet iyi iş çıkarıyor. Otomatik HTTPS sağlıyor, Go ile yazıldığı için bellek güvenliği hataları konusunda endişe yaratmıyor ve sağlam bir file_server modülüne sahip
    • Yıllardır Caddy kullanıyorum. Otomatik SSL sertifikaları, dosya sunumu ve reverse proxy sağlıyor; yapılandırması da çok kolay ve net. Go tekil binary olduğu için “kurulum”u kolay, yapılandırma dosyası da tek bir dosya
    • Caddy, yapılandırıp statik dosya sunmak için oldukça basit
    • Merecat: https://github.com/troglobit/merecat/
  • Aptalca bir soru olabilir ama Bitwarden neden baştan kimlik doğrulaması olmadan /attachments isteklerine izin verdi? Nginx hatası olsa bile bu URL kimlik doğrulaması isteseydi istek başarısız olmaz mıydı?

    • Bu, web sunucusu yapılandırmasını hedef alan bir exploit, dolayısıyla Bitwarden'ın kimlik doğrulama kodu ya da genel olarak Bitwarden kodu hiç çalışmıyor. Projenin Nginx ya da modülü yerine kendi kimlik doğrulamasını kullanması garip ya da yanlış bir şey değil
      Yine de Docker üzerinden riskli bir yapılandırma dağıttıkları için sorumluluk Bitwarden'da. Görünüşe göre Bitwarden da bunu kabul etti ve sonradan düzeltti
  • Aptalca bir soruyu mazur görün. Uygun dizin ve dosya sahipliği varsa bu tür bir gezinme engellenmez mi?
    nginx root olarak çalışmıyorsa, nginx kullanıcısına açıkça atanmış dosyalar dışında başka dosyaları nasıl okuyabilir?

    • Elbette engellenebilir. Uygulamayı bir kullanıcıyla, nginx’i başka bir kullanıcıyla çalıştırır, tüm uygulama dosyalarında go-rwx uygular, “static” dosyaların grubunu www-data yapıp sadece g+r verirseniz web sunucusu uygulama dosyalarına erişemez
      Bu kelimenin tam anlamıyla uygulama barındırma 101 ve insanlar bunu 20 yıl önce de böyle yapıyordu
    • Ah, 022 umask’ın harikaları. Ben şahsen her zaman diğer kullanıcıların dosyaları okuyamamasını sağlamayı öneririm. Tüm dosyalar için yapamıyorsanız en azından /home altı gibi önemli dizinlerde bunu yapın
      Grup üyelikleriyle biraz daha uğraşmanız gerekebilir ama kesinlikle değer
    • Başkaları nasıl yapıyor bilmiyorum ama artık kişisel kullanım için nginx’i düzgün şekilde kurmuyorum. Sadece bir Docker imajı ayağa kaldırıyorum. Ve onun root olarak çalışıp çalışmadığını da gerçekten kontrol etmiyorum
      Belki de gerçekten çok kötü bir şey yapıyorumdur. Ah
    • Varsayılan umask genelde 022 olduğundan çoğu durumda nginx worker’ları okuyabilir ama yazamaz. www-data gibi bir kullanıcıya açıkça atanması da gerekmez. Uygulama hassas veri üretiyorsa tabii ki 077 umask kullanmak daha iyidir
    • Doğru
      Ne yazık ki nginx ve diğer web sunucularının tipik web uygulamalarında çoğu zaman root olarak çalışması gerekir. Çünkü 80 veya 443 portlarında dinleme yapmaları gerekir. 1024 altındaki portları yalnızca root açabilir
      Daha ayrıntılı açıklama burada: https://unix.stackexchange.com/questions/134301/why-does-ngi...