- HTTP çerezleri: Web’de durumu korumak için kullanılan küçük veri parçalarıdır; tarayıcı tarafından ayarlandıktan sonra süreleri dolana kadar tüm HTTP isteklerine eklenir.
- Sorunun ortaya çıkışı: Belirli bir JavaScript kodu, Go standart kütüphanesinde çerezleri ayrıştıramadığı için hataya yol açtı.
Spesifikasyon
- RFC 2109, 2965, 6265: Çerezlerin ilk tanımı ve güncellemeleri. Çerez değerlerine ilişkin spesifikasyon, sunucu ile tarayıcı arasında tutarlı değil.
- Sorunlar:
- Sunucunun göndermesi gereken ile tarayıcının kabul etmesi gereken şey birbiriyle örtüşmüyor.
- Tarayıcının sunucuya gönderdiği çerez değerleri için herhangi bir kısıtlama yok.
- Standart kütüphanelerin çerez başlıklarını nasıl işlemesi gerektiğine dair net bir rehber yok.
Web tarayıcıları
- Firefox: RFC’nin önermediği bazı karakterlere izin veriyor.
- Chromium: Firefox’tan biraz daha kısıtlayıcı, ancak yine de birçok karaktere izin veriyor.
- Safari: İzin verilmeyen bir karakterle karşılaştığında çerez işlemeyi durdurmak yerine, değerin o karaktere kadarki kısmını kabul ediyor.
Standart kütüphaneler
- Golang: RFC’ye benzer davranıyor, ancak boşluk ve virgüle izin veriyor.
- PHP: Belirli kontrol karakterlerinde hata veriyor.
- Python: Anlamadığı çerezleri yok sayıyor ve ek çerezlerin yüklenmesini durduruyor.
- Ruby: Tüm karakterleri kabul ediyor ve percent-encoding uyguluyor.
- Rust: Tüm UTF-8 dizelerini kabul ediyor.
Web için önemi
- Gerçek sorun: Spesifikasyondaki belirsizlik yüzünden birçok web sitesi kolayca hataya açık hale gelebiliyor.
- Çözüm: IETF HTTP Working Group, çerez spesifikasyonunu güncellemeli ve tarayıcılar ile programlama dillerinin çerezleri nasıl işlemesi gerektiğini netleştirmeli.
Özet tablo
- Tarayıcı ve dillerde çerez işleme: Her tarayıcı ve dil çerezleri farklı şekilde işliyor. RFC ile uyum düzeyleri de farklılık gösteriyor.
1 yorum
Hacker News görüşü
Cookie'ler beklenmedik sorunlar ve can sıkıcı davranışlar içerir; vakaların %99,95'inde çalışır. Cookie shadowing, aynı ada sahip ama farklı anahtar öznitelikleriyle (domain, path vb.) cookie ayarlandığında ortaya çıkan bir sorundur; backend ya da JS bunun hangi cookie olduğunu ayırt edemez
Rust'ın standart kütüphanesinde cookie işleme yoktur ve üçüncü taraf
cookiecrate'inin davranışı referans alınır. Bu, Ruby'deki gibi percent-encoding seçeneği içerirHTTP protokolü sayısız başka protokolü içinde barındırır ve tarayıcılar ile web sunucuları çeşitli özellikler ekler. Bu özelliklerin net bir spesifikasyonu yoktur ve istemci ile sunucu uyumluluğu belirleyemez. Bu yüzden geçmişteki kötü kararları sürdürmek zorunda kalınır
Yaklaşık 10 yıl önce bir projede cookie tabanlı session uyguladığımda, Safari'de çalışıp Chrome'da çalışmayan bir sorun yaşamıştım. Bunun nedeni, doğru formatta değilse tarayıcıların cookie ayarlamama konusundaki farklarıydı
Cookie'lerin tek makul kullanımı, sunucunun istemciyi tanıyabilmesi için opak bir token ayarlamaktır. İstemcinin sunucunun göndermeyeceği değerleri işleyebilmesi başlı başına sorun değildir
Cookie'ler karmaşık bir problemdir ve geriye dönük uyumluluk sorunları nedeniyle değiştirilmeleri neredeyse imkansızdır. Yeni bir mekanizma yaratmaya ihtiyaç vardır. Örneğin NewCookie mekanizması modern güvenlik önlemlerine ve katı bir spesifikasyona sahip olabilir
Cookie'ler ortadan kalkmalı ve yerlerini Authorization header alabilmelidir. Tarayıcıda web sitelerine standart bir şekilde kimlik doğrulama yapılabilse iyi olurdu. Basic ve Digest authentication'ın yeterli olmamış olması üzücü
Safari'nin networking kodu open source olmadığından, Swift'in Foundation portu iyi bir alternatif olabilir. Kontrol ve silme karakterleri burada kontrol edilebilir
Cookie header parsing kafa karıştırıcıdır. "Standart" gerçekte var olanı yansıtmaz ve her backend sunucusu, kütüphane ya da framework farklı şeyleri kabul eder. Frontend ve backend'i tamamen kontrol edebiliyorsanız büyük sorun değildir, ancak başka sistemlerle etkileşime girmek gerektiğinde çok karmaşık hale gelir
Crystal diliyle deney yaparken benzer bir sorun yaşamıştım. Basit bir web scraper kurmaya çalışıyordum ama varsayılan HTTP client, yanıtta ayarlanan birçok cookie'yi parse edemeyip duruyordu