← Radar

Konu: Güvenlik2 dk okuma

PHP'nin 20 yıllık hatası: yönlendirmede token başka siteye gidiyordu

Bu neden önemli?

API anahtarını başlıkta gönderen herkes bu tür bir sızıntıdan etkilenebilir. Sorun PHP'ye özel değil: bir HTTP istemcisi yönlendirmede gizli bilgiyi nereye taşıyacağına nasıl karar veriyor, bunu bilmek her dilde işe yarıyor.

Ne oldu?

PHP’de file_get_contents() ve fopen() bir http:// ya da https:// adresini doğrudan açabiliyor. İstek başlıklarını (örneğin Authorization: Bearer ...) bir “stream context” ile veriyorsun. Yönlendirmeyi takip etmek de varsayılan olarak açık.

Sorun şuydu: Gittiğin sunucu seni başka bir siteye yönlendirirse (302 gibi), PHP aynı isteği aynı başlıklarla yeni adrese de gönderiyordu. Yani Authorization, Cookie ve Proxy-Authorization başlıkların, hiç tanımadığın bir sunucuya gidebiliyordu. Port değişse ya da HTTPS’ten düz HTTP’ye düşse bile aynı şey oluyordu; bu durumda token şifresiz ağdan geçer.

Hata CVE-2026-91766 olarak kayıtlı, önem derecesi “orta” (CVSS 5.9). Düzeltme 24 Eylül 2026’da şu sürümlerle geldi: 8.2.34, 8.3.35, 8.4.26 ve 8.5.11. Bu sürümlerden eskilerini kullanıyorsan etkileniyorsun.

Neden “20 yıllık”?

Düzeltmeyi yazan Alexandre Daubois’ın anlattığına göre davranış, bu bağlam seçeneklerinin eklendiği 2003 tarihli koda kadar uzanıyor. Yönlendirme kodu en baştan “aynı isteği başka yerde tekrarla” mantığıyla yazılmış. Yıllar içinde POST’un GET’e dönüşmesi gibi ayrıntılar düşünülmüş, ama isteğin hâlâ aynı sunucuya gidip gitmediği hiç kontrol edilmemiş.

İlginç bir karşılaştırma: curl aynı hatayı 2018’de (CVE-2018-1000007), port ve şema farkını da 2022’de (CVE-2022-27776) kapattı. PHP bu iki düzeltmeyi de şimdi almış oldu.

Düzeltme ne yapıyor?

Yeni kod, yönlendirmeden önce şemaya, sunucu adına ve porta bakıyor. Üçü de aynı değilse Authorization, Cookie ve Proxy-Authorization başlıklarını bir sonraki isteklerden çıkarıyor. Bu bayrak zincirde kalıcı: yönlendirme sonradan ilk sunucuya geri dönse bile token geri verilmiyor. Başka bir başlığı (X-Custom gibi) silmiyor.

Senin için anlamı

  • PHP kullanıyorsan sürümünü yükselt. Hemen yükseltemiyorsan, URL açan çağrılarda follow_location değerini 0 yap, yönlendirmenin nereye gittiğini kendin kontrol edip öyle takip et.
  • Gizli bilgiyi X-Api-Key gibi kendi başlık adında taşıyorsan, düzeltme bu başlığı da silmez. Yukarıdaki yöntem bu durumda da geçerli.
  • Başka dillerde de kural farklı: yazara göre Go, alt alan adlarına (sub.foo.com) gizli başlıkları taşımaya devam ediyor; Python’daki requests ise standart portlarda HTTP’den HTTPS’e geçişte Authorization’ı koruyor. Kullandığın istemcinin kuralını bilmek iyi.

Düşün

  • Kodunda token’ı hangi çağrılarla gönderiyorsun ve o çağrılar yönlendirme takip ediyor mu?
  • Bir kütüphanenin “güvenli varsayılanı” olduğuna ne kadar güveniyorsun, son kez ne zaman kontrol ettin?

Videoyu izle

Tıklayınca video YouTube'dan yüklenir; o ana kadar bu sayfa YouTube'a hiçbir istek göndermez.
Kaynaklar (4, İngilizce)

Kendi cümlelerimizle yazılmış bir özettir, çeviri değildir. Tüm kaynaklar yukarıda.