1 puan yazan GN⁺ 5 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • Chris Morgan, kendi sitesinde izinsiz sorgu dizelerini tamamen engellemeye karar verdi; mevcut uygulama şu anda Caddyfile içinde yer alıyor
  • URL’ye ?ref=example.com gibi izleme amaçlı parametreler eklenmesini istemiyor; gerekirse Referer başlığına bakılabileceğini düşünüyor
  • ?utm_source=example&utm_*&c.* gibi UTM parameters, ona göre site sahibinin kullanımı içindir; dışarıdan eklenmemelidir
  • Site şu anda sorgu dizelerini hiç kullanmıyor ve ileride kullanırsa yalnızca bilinen parametrelere izin vermeyi planlıyor
  • Son URL olarak /no-query-strings seçildi; /%3F ise Caddy’nin try_files yeniden yazımında sorun çıkardığı için tercih edilmedi

İzinsiz sorgu dizelerini engelleme

  • Chris Morgan, kendi sitesinde izinsiz sorgu dizelerini tamamen engellemeye karar verdi
  • ?ref=example.com gibi izleme amaçlı parametrelerin kendi URL’lerine eklenmesini istemiyor; gerekirse Referer başlığına bakılabileceğini düşünüyor
  • ?utm_source=example&utm_*&c.* gibi UTM parameters, ona göre site sahibinin kullanımı içindir; dışarıdan eklenmemelidir
  • Bu site şu anda sorgu dizelerini hiç kullanmıyor ve ileride kullanırsa yalnızca bilinen parametrelere izin vermeyi planlıyor
  • Geçmişte stil sayfası URL’lerinde ?t=…, ?h=… biçiminde önbellek geçersiz kılma URL’leri kullanmıştı, ancak bu tür isteklerin bozulmasının sorun olmayacağını düşünüyor
  • Bu engelleme şu anda Caddyfile içinde uygulanmış durumda

URL seçme süreci

  • /? kullanma planı

    • İlk başta bu sayfayı https://chrismorgan.info/? adresinde yayımlama fikri çok cazip gelmişti
    • Boş yol ve boş sorgu biçimi olduğundan, yaygın ama hatalı birçok varsayımı bozuyor ve bazı araçları zor durumda bırakabiliyordu
    • curl, komut satırında sondaki soru işaretini haksız yere kaldırıyor gibi görünüyordu; kütüphane kullanımı test edilmedi
    • Sonunda yol kavramına saygı göstermeye ve insanlara karşı daha anlayışlı olmaya karar verdi; özellikle de Caddy’yi zaten yeterince rahatsız edici bir yöne zorladığını düşündü
  • /%3F kullanma planı

  • Nihai seçim

    • Nihai URL olarak /no-query-strings seçildi
    • /? veya /%3F, ileride sorgu dizeleriyle ilgili başka bir amaç için kullanılabilir

1 yorum

 
GN⁺ 5 시간 전
Hacker News yorumları
  • Bunu merak edip HTML ve URL W3C standartlarına yeniden baktım; şaşırtıcı biçimde sorgu dizesi biçimi için yüzde kodlaması dışında ayrı bir tanım yoktu.
    Sorgu dizesini “form-urlencoded”[0] sorgu dizesiyle karıştırmak mümkün, ama bu sadece birlikte çalışabilir biçimlerden biri. Genel olarak sorgu dizesi, URL içindeki ? işaretinden sonra gelen herhangi bir yüzde kodlu dizgedir[1] ve yanıt üretiminde kullanılabilen HTML URL nesnesinin başka bir özelliğidir.
    URLSearchParams nesnesi, sorgu dizesinin form-urlencoded ayrıştırıcısıyla ayrıştırılmış sonucudur, ama bu sadece JavaScript için bir birlikte çalışabilirlik katmanıdır.
    Dürüst olmak gerekirse, standarda bakmadan önce karşı çıkmaya hazırdım, ama standart oldukça açıktı. Beklenmeyen sorgu dizelerine 404 ile yanıt vermek de uygun olabilir. Sorgu dizesi de yol kadar URL API’sinin bir parçası ve yola rastgele dizgeler eklemenin iyi olmadığı ve tanımsız davranış olduğu konusunda çoğumuz hemfikir olabiliriz.
    [0]: https://url.spec.whatwg.org/#application/x-www-form-urlencod...
    [1]: https://url.spec.whatwg.org/#url-class

    • Eskiden CMS’lerin ya da forumların sadece tek bir index.php dosyası bulundurup tüm yönlendirmeyi sorgu dizesi üzerinden yapması oldukça yaygındı.
      Elbette form-urlencoded biçimindeydi; insanlar da barbar değildi. Bu yüzden index.php?p=home, index.php?p=shop ya da index.php?action=showthread&forum=42&thread=17976 gibi URL’ler görürdünüz. Böyle bir yapıda, bilinmeyen sorgu parametrelerine 404 dönmenin doğru yanıt olduğu hemen ortaya çıkar.
      Aslında bugün bile birçok site böyle çalışıyor, sadece SEO nedeniyle birkaç Apache/nginx yeniden yazma kuralının arkasına gizlenmiş durumda.
    • Evet, URL’lerde o kadar da fazla anlambilim yok. Yolun hiyerarşik veri, sorgunun ise hiyerarşik olmayan veri için tasarlandığı açıkça görülüyor; güçlü gelenekler de var ve bazılarını kütüphaneler destekliyor ya da dayatıyor, ama gerçek kurallar yok.
      Sonuçta URL, sunucunun nasıl işleyeceğine karar verdiği bir dizgeden ibaret.
      Bu tartışmadaki gerçekten komik şey, 404 döndürmenin yan etkilerinden kaygılanırken web tarihinde yolların ne kadar uzun süre anlamsız olduğunu tamamen unutmuş olmamız. Artık yolu kazandı. Yeni bir şeye /item?id=… gibi URL’lerle başlanması neredeyse hiç olmuyor. Güzel!
    • Bence genel amaçlı bir 400 daha iyi olabilir. Sonuçta sayfa bulunamadı değil, izin verilmeyen bir istek gönderildi.
      Bu, “isteği düzeltip yeniden dene” diye okunuyor ve sunduğum API’de de bunu kullanıyorum. 406 yerine bunu tercih etmemin nedeni, sorunun benim tarafımda işlenememesi olmaması. Sorgu dizesine bir şeyler ekleyip bozmayı denediyseniz ya da isteği belgelere uygun kurmadıysanız, sorumluluk isteği gönderende.
    • No-Vary-Search önerisi, sorgunun hangi kısımlarının ilgili olduğunu belirtmeyi sağlıyor.
      https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/...
      Örneğin önbellekleme açısından url?a=b&c=d, url?c=d&a=b ile eşleşiyor sayılabilir.
    • Standartlar, birilerinin bir yerde yazdığı ve yaygın kabul gören davranışlardan ibarettir.
      Hiçbir zaman resmî standart olarak belgelenmemiş olsa da uyulmazsa geniş çapta bozulmaya yol açan pek çok gelenek var; bir de harfi harfine uyarsanız sizi aptal durumuna düşüren “standartlar” var.
      Asıl yazıdaki durumda bozulan şey, sadece o siteyi ziyaret etmeye çalışan insanlar olur; büyük ihtimalle de tarayıcıda geri düğmesine basıp işlerine bakarlar. Bu düzeyde zararı kabul edip etmeyeceğine kişi kendi karar verir. Ama hiçbir standardın yasaklamamış olması, tanım gereği izinli olduğu anlamına gelmez; tersine, bir standardın yasaklamış olması da bir şeyi bir anda yasaklı yapmaz.
  • Anladığım kadarıyla, başka sitelerin yazarın sitesine verdiği bağlantılara ?ref=origin.com gibi sorgu dizeleri eklemesine sinirlenmiş.
    Bunun kaynak siteye ne fayda sağladığını ve yazarın sitesine ne zarar verdiğini anlayamıyorum.
    Her iki tarafın davranışı da tamamen kafa karıştırıcı görünüyor.
    Bir reklam kampanyası yürütürken Google’ın UTM sorgu dizeleri ekleyip kullanıcının hangi kampanyadan geldiğini izlemek istemesini anlıyorum. Orada kaynak ve hedef işbirliği içindedir. Ama burada kaynak taraf görünürde hiçbir sebep yokken bir şey ekliyor. Neden?

    • Kaynak site açısından bu pazarlama. Yazar, ref sorgu dizesinde xyz.com üzerinden ciddi trafik geldiğini görürse, o siteye reklam vermeyi ya da iş ortaklığı yapmayı düşünebilir.
      Dürüst olmak gerekirse, niş/startup siteler için oldukça faydalı olabiliyor. Web analitiğinde bu tür değerlerden doğan konuşmaların iki tarafını da yaşadım; birinde gelen trafiği görüp ben ulaştım, diğerinde bağlantı verdiğim site bana ulaştı. İkisi de her iki taraf için faydalı ortaklıklara dönüştü.
      Gizlilik itirazını bir ölçüde anlıyorum ama standart Referer başlığından daha fazla bilgi vermiyor. Simple Analytics/Plausible gibi analiz araçları kullanırsanız sadece çok daha görünür hale geliyor.
    • Genel olarak izlemeye karşıyım. İzleme çoğu zaman bireyin çıkarına aykırıdır.
      Sorgu dizesi eklemek de sık sık izleme için kullanılır. Firefox’taki “copy clean link” ya da bazı UTM parametrelerini proaktif biçimde kaldıran Enhanced Tracking Protection gibi özelliklerin varlığı bile birçok insanın bunu istemediğini gösteriyor.
      Bazı siteler benim kabaca “izleme ekonomisi” dediğim sisteme isteyerek katılıyor. Çünkü alıcı, günlüklerde çok sayıda kişinin o siteden geldiğini görüp o siteye yarar sağlayan adımlar atabiliyor.
      Sorgu dizelerini reddetmek de bu sisteme karşı basit bir protestodur.
    • Popüler bir web sitesi bu parametreyi eklerse, hedef site trafiği kimin gönderdiğini kolayca anlayabilir ve bu da sponsorluk ya da ortaklık anlaşmalarının temeli olabilir.
  • “Web sitesi ziyaretçilerinin, bağımsız kişisel web sitesi işletmecileri topluluğunun önerdiği ilginç web siteleri ve sayfaları keşfetmesini sağlayan küçük, merkeziyetsiz, self-hosted bir web konsolu” açıklamasını görünce, eskiden buna Webring denirdi. Sadece bu kadar süslü değildi.
    Açık kaynak bir uygulama çatısı geliştirirken yaşadığım sorunlardan biri, FastCGI kullanan barındırmanın Auth başlığını dikkate almamasıydı; bu yüzden token’ı sorgu üzerinden geçirmek zorunda kalıyordum. Web adreslerini kopyalayıp yapıştırırken token’ın içine karışması gerçekten berbattı. Belki şimdi düzelmiştir.
    Kontrol ettiğim ve herkese açık olması gerekmeyen arka uçlarda başlık kullanıyorum.

    • Açık kaynak uygulama çatısını fcgi-app ile yazdığınızı söylediniz; yani örneğin Apache Auth başlığını bozuyordu, öyle mi?
      Bunu biraz daha ayrıntılı açıklayabilir misiniz diye merak ediyorum. Teknik olarak bu, PARAM kaydının beklediğiniz değeri fiilen vermemesi gibi görünüyor.
  • “Bu yüzden bu sitede kapsamlı bir yasak denemeye karar verdim: onaylanmamış sorgu dizesi yok” demiş, ama görünüşe göre sitesi istekte sorgu dizesi varsa 414 döndürüyor ve bence bu yanlış bir seçim.
    Bu protesto kullanıcıyı savunmak içindeyse, başlangıçta o dizge üzerinde kontrolü bile olmayan kullanıcıyı neden cezalandırıyor?
    Bunu, kullanıcının tarayıcı araçları vb. üzerinden bu kararı kendisinin verebilmesini sağlayacak bir işaret olarak kullanmak daha iyi olmaz mı?

    • “Benim 414 URI Too Long’u kötüye kullandığımı iddia edebilirsiniz. Benim cevabım şu: bu daha komik. Düşündüğüm diğer seçenekler şunlardı:
      400 Bad Request, genel amaçlı istemci hata kodu olarak uygun ama eğlenceli değil.
      402 Payment Required, dürüst olmak gerekirse sorgu dizesi içeren belirli URL’lerin çalışması için para ödemek isterseniz buna açığım.
      404 Not Found, ama bunun yan etkileri çok kolay ortaya çıkıyor ve vermek istediğim ‘istek biçimi yanlış’ duygusunu iletmiyor.
      Location başlığı olmadan 303 See Other. Günümüzde son derece nadir ama meşru. En azından RFC 2616’da öyleydi (“The different URI SHOULD be given by the Location field in the response”). Ama 7231 ve 9110’da, Location başlığının varlığını varsayacak şekilde değişti (“… as indicated by a URI in the Location header field”). Buna karşılık 301, 302, 307, 308 için “the server SHOULD generate a Location header field” deniyor. Her hâlükârda Location başlığı olmayan bir See Other’ın da yeterince makul olduğunu düşünüyorum. Ama URI Too Long daha komikti.”
      https://chrismorgan.info/no-query-strings?foo
    • Çok eskiden kalma silik bir anım var ama, bilinmeyen sorgu dizeleri gönderildiğinde 500 döndüren bir PLSQL sunucu sayfası sürümü vardı galiba.
  • “Benim 414 URI Too Long’u kötüye kullandığımı iddia edebilirsiniz. Benim cevabım şu: bu daha komik. Düşündüğüm diğer seçenekler...” kısmında, başka bir seçenek olarak 418 I'm a teapot da düşünülebilir. Sonuçta çaydanlıklar da genelde sorgu dizelerini desteklemez.

    • Basitçe 400 “Bad Request” ya da 403 “Forbidden” da savunulabilir seçimler gibi görünüyor. URI parametrelerine özel bir hata yanıt kodu olmaması tuhaf.
      Uygun gibi görünüp yakından bakınca öyle olmayan birkaç seçenek daha var: 406 “Not Acceptable” içerik uzlaşması başlıklarına dayanır, 409 “Conflict” esasen WebDAV istekleri içindir, 411, 422, 431 gibi kodlar da burayla ilgisi olmayan daha özel koşullara yöneliktir.
      300 ya da 500 serisi hatalar da uygun değil. Bu bir yeniden yönlendirme ya da sunucu tarafı arızası değil, istemci taraflı bir istek sorunu.
      En iyi adaylar çaydanlık ya da fazla uzun olan gibi duruyor.
    • Elbette destekler. Örneğin yukarıdan aşağıya doğru çaydanlığın doluluk seviyesini sorgulayabilirsiniz; ya da ipi çaydanlığın etrafına sarıp çevresini sorgulayabilirsiniz.
    • Ama ben çaydanlık değilim. Çayı sevmem.
  • Bu yazının ve Chris’in yazısının tonuna bakınca, bu tür sorgu parametrelerini eklemek zararlıymış gibi geliyor ama nasıl zararlı olduğunu anlayamıyorum.
    Bazı URL’leri bozabileceğini anlıyorum ve bu bile yapmamak için yeterli bir sebep. Yine de küçük bir rahatsızlık gibi görünüyor. Bunu açıklayabilecek biri var mı?

    • Üç açıdan bakılabilir.
      Teknik saflık açısından, geleneksel olarak kabul ediliyor olsa bile URL’yi değiştirmek teknik olarak yanlıştır. URL’ler temelde opak değerler olarak ele alınmalıdır.
      Toplumsal açıdan bu bir izleme biçimidir; kardeş yorum dizileri bunu gayet iyi açıklıyor, tekrar etmeyeceğim.
      Gürültü açısından ise, kullanıcının önemsemesi gereken şeyleri görünmez kılar ve URL’leri o kadar zor ve karmaşık hale getirmeye katkı sağlar ki sıradan insanlar artık URL’lerle ilgilenmemeye başlar.
    • HTTP Referer başlığıyla ilgili sorunları okursanız insanların neden bundan hoşlanmadığını anlayabilirsiniz: https://en.wikipedia.org/wiki/HTTP_referer
      Bir siteye ulaşmadan önce nerede olduğunuzu o sitenin bilmesini istememenin pek çok nedeni var. Esasen ziyaret ettiğiniz siteyle tarama geçmişinizi paylaşıyorsunuz.
      Bu yüzden HTTP Referer başlığı için iletim koşullarını sınırlayan ve özelliği tamamen kapatabilen birçok güncelleme yapıldı.
      Aynı bilgiyi URL parametresi olarak eklemek, bu mevcut kuralları ve reddetme mekanizmalarını dolanmak anlamına gelir. Sadece standardı kullanın.
    • Hiçbir gerekçe yok. O bilgi doğrudan çöpe atılabilir.
      Gülünç derecede aşırı bir tavır ve bunun daha iyi bir web’e nasıl katkı sağladığını gerçekten açıklayamıyor.
    • İlginç olan, bu tür sitelerin bazılarında arama işlevi bile olmaması. Oysa arama önemli bir erişilebilirlik özelliği ve sorgu dizelerinin açık, meşru bir kullanım örneği.
    • Birkaç nedeni var. Kullanıcı izlemeye onay vermedi ve bu tür sorgu parametreleri izleme verisi taşıyor. Ayrıca site yöneticisi gelen trafiğin izlenmesini istemeyebilir.
      İkincisini anlamak daha zor olabilir ama kendi adıma, günlüklerimde kullanıcıya zarar verebilecek bilgilerin kalmasını asla istemem.
      Kişisel olarak, bir bağlantıyı kopyalayıp mesajla gönderecekken orijinal URL’nin iki katı uzunluğunda izleme kodu eklenmiş olmasından gerçekten nefret ediyorum. Ya tek tek silmem gerekiyor ya da karşı tarafın ekranı dolduran rastgele karakterlere bakıp bunun ne olduğunu merak etmesine izin vermem gerekiyor.
      Kullanıcı gizliliğini ihlal ediyor, kullanıcı deneyimini kötüleştiriyor ve hepsinden önemlisi bunu kimse istemedi.
  • Asıl kaynak metin henüz HN’de tartışılmadığı için, o bağlantıyı (https://chrismorgan.info/no-query-strings) en üste koydum ve yanıt yazısının bağlantısını (https://susam.net/no-query-strings.html) üst açıklamaya taşıdım.
    İkisi de iyi ama asıl yazıya öncelik vermek daha adil görünüyor.

  • Bu civarda hâlâ GET sorguları kullanan sitelerin çoğu, oturum açtıktan sonra değişkenleri oradan oraya taşıyan yerel yönetimlere ait vergi tahsilat siteleri.
    Aslında GET isteğinin yaptığı şeyin aynısını yapıp yine de gerçek URL’miş gibi davranan yönlendirme ayrıştırıcıları çok daha sinir bozucu.

  • Sorgu dizelerinin bir kullanım değeri var. Örneğin dosya arama ya da başka türden dinamik dosyalar için işe yararlar; ama sorgu dizesi beklenmeyen URL’lere eklenmemelidirler.
    Bu yüzden UTM gibi şeyler eklenmiş istekleri reddetmenin doğru olduğunu düşünüyorum.
    Sorgu dizesi beklenmiyorsa ama yine de varsa, yanıt olarak 404 en mantıklısı gibi görünüyor; 400 da uygun olabilir.