"Bu URL'yi Kontrol Et" Araçları Neden SSRF Koruması Gerektirir
Verdiğiniz bir URL'yi çeken herhangi bir sunucu tarafı özellik, onun yerine iç adreslere ulaşmaya kandırılabilir — bu saldırı nasıl görünür ve gerçekten nasıl durdurulur?
· 2 dk okuma
Verdiğiniz bir URL'yi çeken bir araç — başlıklarını kontrol etmek, yönlendirmelerini takip etmek, ya da bağlantılarını taramak için — aksi halde sıradan görünen yazılımlarda gerçek bir güvenlik hatasının ortaya çıktığı en yaygın yerlerden biridir. Bu hatanın bir adı vardır: Server-Side Request Forgery (SSRF), ve şekli her zaman aynıdır. Giden isteklere hiçbir kısıtlaması olmayan bir sunucu, https://example.com'a bağlandığı kadar isteyerek http://169.254.169.254/ veya http://localhost:6379'a da bağlanır, çünkü onun bakış açısından hepsi yalnızca birer URL'dir.
O belirli adres neden önemli
169.254.169.254, bulut sağlayıcılarının (AWS, GCP, Azure) kendi instance metadata servisi için kullandığı link-local adresidir — bir VM'in kendi geçici kimlik bilgilerini almak için sorguladığı uç nokta. Halka açık bir "bir URL yapıştır, ben çekeyim" özelliği o adrese yönlendirilebilirse, bir saldırgan yalnızca sunucunun kendisi için amaçlanan kimlik bilgilerini okuyabilir. Gerçek dünyadaki en yaygın tek SSRF hedefidir, ve aynı zamanda 127.0.0.1 veya 10.0.0.5 gibi yalnızca özel bir ağ adresidir — güvenlik açığı o IP'ye özgü değildir, herhangi bir iç adresin hiç erişilebilir olmasıdır.
Saf çözüm işe yaramaz
Bir URL'nin hostname'inin "iç gibi göründüğünü" kontrol etmek (localhost'u engellemek gibi), gerçekte nereye çözüldüğünü kontrol etmekle aynı şey değildir. DNS onu çözene kadar bir hostname yalnızca bir string'dir — ve DNS, tamamen sıradan görünen bir isim için özel bir adresle yanıt verecek şekilde ayarlanabilir. Gerçek bir çözüm, bağlanmadan önce hostname'i çözmeli ve gerçek IP adresini incelemelidir, URL'nin metnine göre desen eşleştirmesi yapmamalıdır.
Doğru yapılması gereken ikinci bir katman daha var: yönlendirmeler. Bir URL kendi başına her kontrolden geçebilir ve sonra tamamen başka bir yere işaret eden bir 30x ile yanıt verebilir — hemen http://localhost/admin'e yönlendiren halka açık bir giriş noktası. Güvenli bir fetch, yönlendirmeleri elle takip etmeli (bunu HTTP istemcisinin otomatik davranışına devretmemeli) ve her tek adımı, yalnızca ilkini değil, aynı kurallara karşı yeniden doğrulamalıdır.
Gerçek savunma nasıl görünür
Bir araya getirildiğinde, güvenli bir giden fetch şunları yapmalıdır:
- Şemayı
http/httpsile sınırlamak —file://yok,gopher://yok. - Hostname'i çözmek ve çözülen adreslerden herhangi biri özel, loopback, link-local veya ayrılmış bir aralığa düşerse isteği reddetmek (tüm
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.0/8,169.254.0.0/16listesi, artı IPv6 eşdeğerleri). - Hedef istek ortasında değişebileceğinden, aynı kontrolü her yönlendirme adımında yeniden çalıştırmak.
- Zaman aşımını ve yanıt boyutunu sınırlamak, böylece izin verilen bir hedef bile sunucuyu süresiz olarak meşgul etmek için kullanılamaz.
HTTP Başlık Kontrolü, Yönlendirme Zinciri Kontrolü ve Kırık Bağlantı Tarayıcı hepsi ziyaretçinin verdiği bir URL'yi sunucu tarafında çeker (bir tarayıcının kendi CORS kısıtlamaları bunu rastgele bir site için istemci tarafında yapmayı imkansız kılar), bu yüzden üçü de bir bağlantı açmadan önce tam olarak bu kontrol listesini uygular. SSL Sertifika Kontrolü aynı adres doğrulamasına ihtiyaç duyar ama bir HTTP fetch hiç kullanamaz — bir TLS sertifikası okumak doğrudan ham bir soket açmak demektir, bu yüzden hostname o soket hiç çevrilmeden önce aynı şekilde kontrol edilir. DNS Sorgulama bu gruptaki, yapısı gereği bunların hepsinden muaf olan tek araçtır: yalnızca genel bir DNS resolver'ına bir ismin neye eşlendiğini sorar ve geri aldığı adrese asla bağlanmaz, bu yüzden hedef adresin kendisinin saldırabileceği hiçbir şey yoktur.

