- Uzun süre çalışan arka uçlara istekleri soket üzerinden aktaran bir proxy protokolü olarak, mevcut HTTP işleyici yapısını neredeyse hiç değiştirmeden uygulanabilir
- HTTP/1.1 ters proxy kullanımında mesaj sınırlarının yorumlanması implementasyondan implementasyona kolayca sapabilir; bu da desync ve request smuggling gibi ciddi güvenlik sorunlarını sürekli üretebilir
- FastCGI, 1996'dan beri açık mesaj çerçevelemesi sağlıyor ve istemci başlıklarıyla proxy'nin eklediği güvenilir bilgileri yapısal olarak ayırıyor
- Go'nun
net/http/fcgipaketi,REMOTE_ADDRdeğeriniRequest.RemoteAddriçine dolduruyor ve HTTPS durumunu daRequest.TLSalanına yansıtıyor; böylece güvenilir bilgi aktarımı ek bir middleware olmadan yapılabiliyor - WebSockets desteği olmaması, zayıf araç ekosistemi ve bazı iş yüklerinde daha düşük throughput gibi sınırlamalar var; ancak WebSockets gerekmiyorsa ve performans yeterliyse hâlâ pratik bir seçenek gibi görünüyor
FastCGI'nin konumu ve uygulama biçimi
- FastCGI, yalnızca dosya başına süreç çalıştırma modeli için değil, uzun süre çalışan daemon'lara TCP veya UNIX soketi üzerinden istek gönderen bir proxy-arka uç protokolü olarak da kullanılabilir
- Go'da
net/http/fcgipaketini içe aktarıphttp.Serveçağrısınıfcgi.Serveile değiştirmek çoğu zaman yeterlidir- Mevcut işleyiciler aynı şekilde
http.ResponseWritervehttp.Requestkullanır - Uygulamanın geri kalan yapısı da olduğu gibi korunur
- Mevcut işleyiciler aynı şekilde
- Apache, Caddy, nginx, HAProxy gibi başlıca proxy'ler FastCGI arka uçlarını destekler ve yapılandırmaları da görece basittir
HTTP'yi arka uç protokolü olarak kullanırken ortaya çıkan ayrıştırma sorunları
- HTTP reverse proxying, güvenlik mayın tarlasına yakındır; Discord medya proxy'sindeki desync zafiyeti gibi, özel ekleri gözetlemeye imkân veren sorunlar da ortaya çıkmaya devam ediyor
- HTTP/1.1, görünüşte basit bir metin protokolü olsa da aynı mesajı ifade etmenin aşırı fazla yolu ve çok sayıda istisna durumu vardır; bu yüzden implementasyonlar arasında yorum farkı çıkması kolaydır
- En büyük sorun, HTTP mesajlarında açık çerçeveleme olmamasıdır
- Mesajın nerede bittiğini mesajın kendisi birden fazla yolla tarif eder
- Farklı implementasyonlar mesajın bittiği yeri ve sonraki mesajın başladığı noktayı farklı yorumlayabilir
- Bu tür uyumsuzluklar, HTTP desync attacks ya da request smuggling için temel oluşturur; ters proxy ile arka uç mesaj sınırlarını farklı anladığında ciddi güvenlik sorunları doğar
- Ayrıştırıcı farklarını sürekli yamamak kökten bir çözüm olmaya pek uygun görünmüyor
- James Kettle sürekli yeni türler bulmaya devam ediyor
- Geçen yıl ek örnekler bulduktan sonra "HTTP/1.1 must die" ifadesini bile kullandı
FastCGI ve HTTP/2'de mesaj sınırlarının işlenmesi
- HTTP/2, proxy ile arka uç arasında tutarlı biçimde kullanıldığında mesaj sınırlarını netleştirerek desync sorununu çözebilir
- FastCGI ise bu net sınır ayrımını 1996'dan beri daha basit bir protokolle sağlıyor
- nginx ilk sürümünden beri FastCGI arka uçlarını destekliyor, ancak HTTP/2 arka uç desteği ancak 2025'in sonlarına doğru eklendi
- Apache'nin HTTP/2 arka uç desteği ise hâlâ "experimental" durumunda
Güvenilmeyen başlıklar sorunu ve FastCGI'nin ayırma biçimi
- Sorun yalnızca desync değil; HTTP, gerçek istemci IP'si, proxy'nin işlediği kimliği doğrulanmış kullanıcı adı ya da mTLS'teki istemci sertifikası bilgisi gibi proxy'nin güvenle aktarması gereken verileri sağlam biçimde taşımakta da yetersiz kalıyor
- Pratikte bu tür bilgiler HTTP başlıklarına konuyor, ancak proxy'nin eklediği güvenilir veriler ile istemcinin gönderdiği güvenilmeyen başlıklar arasında yapısal bir ayrım yok
X-Real-IPgibi başlıklar gerçek istemci IP'sini iletmek için sık kullanılıyor, ancak güvenli olması için proxy'nin büyük/küçük harf varyasyonları da dâhil mevcut tüm ilgili başlıkları tamamen silip yeniden eklemesi gerekiyor- Bu yaklaşım son derece riskli bir alan ve arka ucun saldırganın enjekte ettiği veriye güvenmesine yol açabilecek pek çok yol var
- Proxy, yalnızca
X-Real-IPdeğil, bu amaçla kullanılabilecek her türlü başlığı temizlemek zorunda - Örneğin Chi middleware'i, istemcinin gerçek IP'sini belirlerken önce
True-Client-IPbaşlığını kontrol ediyor; yalnızca o yoksaX-Real-IPkullanıyor- Proxy
X-Real-IP'yi doğru işlese bile saldırganTrue-Client-IPgönderirse sorun çıkabilir
- Proxy
- FastCGI, istemci başlıkları ile proxy'nin eklediği bilgileri alan ayrımı yoluyla ayırır
- İkisi de anahtar/değer parametre listesi olarak iletilir, ancak HTTP başlık adlarına
HTTP_öneki eklenir - Bu nedenle istemcinin gönderdiği bir başlığın proxy'nin güvenilir verisi olarak yorumlanması yapısal olarak mümkün olmaz
- İkisi de anahtar/değer parametre listesi olarak iletilir, ancak HTTP başlık adlarına
Go'da FastCGI ile güvenilir bilgi işleme
- FastCGI, gerçek istemci IP'sini aktarmak için
REMOTE_ADDRgibi standart parametreler tanımlar - Go'nun
net/http/fcgipaketi bu değeri otomatik olarakhttp.RequestiçindekiRemoteAddralanına doldurur; böylece ek bir middleware gerekmez - Proxy, HTTPS kullanımı, pazarlık edilen TLS cipher suite'i ya da istemci sertifikası gibi bilgileri standart olmayan parametrelerle de iletebilir
- Go, istek HTTPS kullanıyorsa
RequestiçindekiTLSalanını otomatik olarak nil olmayan bir değere ayarlar- Boş olsa bile HTTPS zorunluluğunu denetlemek açısından faydalıdır
fcgi.ProcessEnvile proxy'nin gönderdiği güvenilir parametrelerin tamamına erişilebilir
Neden yaygınlaşmadı ve pratik sınırlamalar neler
- FastCGI daha iyiyse neden yaygın kullanılmadığı sorusuna verilen olası yanıt, adının çağrıştırdığı eskilik hissi ile HTTP reverse proxy güvenlik sorunlarına dair farkındalık eksikliğinin birleşmesi gibi görünüyor
- Watchfire, 2005'te desync saldırılarını zaten ele almış ve çözümün kolay olmadığı uyarısını yapmıştı; buna rağmen bu saldırılar 10 yıldan fazla süre boyunca gerektiği kadar dikkat çekmedi
- FastCGI bugün de gerçek kullanım için uygun ve SSLMate tarafından 10 yıldan uzun süredir production ortamında kullanılıyor
- Yine de eski bir teknoloji olduğu için zayıf yönleri var
- WebSockets desteği için güncellenmedi
- Araç ekosistemi zayıf
- Örneğin curl, FTP, Gopher ve SMTP'yi bile desteklerken FastCGI isteği gönderemiyor
- Go FastCGI sunucusu çeşitli reverse proxy'lerin arkasında benchmark edildiğinde, bazı iş yüklerinde HTTP/1.1 veya HTTP/2'den daha düşük throughput görüldü
- Bu durum, protokolün doğasından çok FastCGI kod yolunun HTTP kadar optimize edilmemiş olmasına bağlanıyor
Son değerlendirme
- WebSockets gerekmiyorsa ve mevcut performans yeterliyse FastCGI hâlâ değerlendirilebilir bir seçenek
- Bir darboğaz oluşsa bile, HTTP reverse proxying'in karmaşıklığı ve güvenlik kâbusunu üstlenmek yerine ek donanım kullanmayı tercih etmek daha mantıklı görünüyor
Henüz yorum yok.