deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

nginx limit_except, HTTP QUERY'yi boş bir 403 ile reddediyor; RFC 10008 testleri bunu gösterdi

RFC 10008'in QUERY metoduna yönelik bir dev.to testi, curl, FastAPI, Caddy ve Traefik'in metodu ilettiğini, Django view'ları ve nginx limit_except yapılandırmalarının ise reddettiğini ortaya koydu.

nginx limit_except, HTTP QUERY'yi boş bir 403 ile reddediyor; RFC 10008 testleri bunu gösterdi

dev.to üzerinde belgelenen pratik bir deney, yeni HTTP QUERY metodunun yaygın web altyapılarındaki durumunu haritaladı ve öne çıkan bulgu bir nginx tuzağı: yaygın şekilde kopyalanan limit_except sağlamlaştırma bloğu, QUERY isteklerini backend'e hiç ulaşmadan önce boş bir 403 ile reddediyor.

QUERY, gönderiye göre Haziran ayında Proposed Standard statüsüne ulaşan RFC 10008'de tanımlanıyor. Metod, GET gibi safe ve idempotent ancak POST gibi bir request body taşıyor; bu da onu, GET'in karmaşık bir filtre nesnesini ifade edemediği ve query string'lerin uzunluk sınırlarına takıldığı tanıdık search-endpoint-over-POST deseninin yerine geçecek bir aday haline getiriyor. RFC'nin kendisi eski proxy, framework ve load-balancer yapılandırmalarının metodu henüz tanımayabileceği konusunda uyarıyor ancak "tanımamanın" pratikte nasıl göründüğüne dair hiçbir şey söylemiyor; yazar da bu soruyu yanıtlamak için bir sunucu kiralamış ve ölçüm yapmış.

Kurulum

dev.to yazısına göre test, Frankfurt'taki tek bir DigitalOcean droplet üzerinde Ubuntu 24.04 ile yapıldı; FastAPI backend'i ayrı portlarda nginx, Caddy ve Traefik tarafından öne alındı, ayrıca Django'nun metodları Starlette'ten farklı dispatch etmesi nedeniyle class-based view kullanan bağımsız bir Django projesi eklendi. Test edilen sürümler: curl 8.5.0, Starlette 1.6.0 üzerinde FastAPI 0.141.1, Django 6.1.1, nginx 1.24.0, Caddy 2.11.4 ve Traefik 3.7.10. Test bittiğinde droplet imha edildi.

Client ve framework davranışı

curl özel bir işlem gerektirmedi: JSON body'li bir QUERY isteği, ham bir netcat listener ile doğrulandığında, hiçbir flag veya workaround olmadan hat üzerinde düzgün biçimlendirilmiş bir istek üretti.

FastAPI, QUERY'yi açıkça kabul edecek şekilde tanımlanmış bir route'da body'yi geri yankılayarak 200 yanıtı verdi ve yalnızca GET kabul eden bir route, Allow: GET, HEAD başlığıyla doğru bir 405 döndürdü. Ancak dikkat edilmesi gereken nokta ayrıntı düzeyi: global bir anahtar yok, dolayısıyla QUERY'ye yanıt vermesi gereken her route metodu tek tek listelemek zorunda.

Django'da ise işler sessizce bozuldu. Class-based view'ler, küçük harfe çevrilmiş metod adıyla aynı isimli bir handler'a dispatch oluyor; bu nedenle bir query() metodu tanımlamak yeterli görünüyor, ancak istek yine de boş body'li ve yalnızca OPTIONS listeleyen bir Allow başlığıyla 405 döndü. Bunun nedeni View.http_method_names'in query içermeyen hardcoded bir liste olması ve Django'nun sınıfa bakmadan önce bu listeyi kontrol etmesi. Listeyi tek satırla, http_method_names = View.http_method_names + ['query'] şeklinde genişletmek, aynı handler'ın body olduğu gibi korunmuş halde 200 döndürmesini sağladı.

nginx tuzağı

nginx'in kendisi sorun değildi. Düz bir proxy_pass ve metodları kısıtlamayan bir yapılandırmayla QUERY istekleri geçti ve 200 döndürdü; on eşzamanlı istek altında bile aynı durum söz konusuydu ve access log bunları yapılandırmada hiçbir değişiklik olmadan kaydetti.

Bozulma, nginx sağlamlaştırma rehberlerinden sıkça kopyalanan bir parçacık olan limit_except kaynaklandı. Bir location'ı deny all ile GET, POST ve HEAD ile sınırlandıran bir yapılandırma, QUERY için açıklamasız bir 403 Forbidden döndürdü ve istek backend'e hiç ulaşmadı. Gönderinin de işaret ettiği gibi, bu nginx'in metodu varsayılan olarak yanlış işlemesi değil; bu, fiil henüz var olmadan yıllar önce yazılmış, o üç metodun bir location'ın sunması beklenen her şeyi kapsadığı dönemden kalma bir sağlamlaştırma deseni. nginx arkasında QUERY dağıtacak herkes, yapılandırmalarındaki tüm limit_except directive'lerini denetlemeli.

Caddy ve Traefik iletiyor

Testteki iki yeni proxy de QUERY'yi varsayılan reverse-proxy kurulumlarıyla, hiçbir değişiklik ve takılacak bir allowlist olmadan işledi: Caddy 2.11.4 Via header'ıyla 200 döndürdü ve Traefik 3.7.10 varsayılan bir file-provider router ile aynıını yaptı. Yazar, bunun RFC'nin eski araçlar hakkındaki uyarısının beklenenden daha iyi karşılandığını gösterdiğini belirtiyor.

Neden önemli

Buradaki başarısızlıklar en kötü şekilde sessizce gerçekleşiyor: bir Django 405'si bir routing yazım hatası gibi, bir nginx 403'sü ise bir izin sorunu gibi görünüyor ve gerçek neden olarak metod desteğini işaret eden bir hata mesajı yok. QUERY'den yana ikna olmuş, özellikle mevcutta POST tabanlı bir arama veya filtre endpoint'i bulunan ekiplerin, yalnızca uygulama framework'üne güvenmek yerine client ile handler arasındaki her katmanı denetlemesi gerekiyor. Bu testten çıkan kontrol listesi somut: Django'nun http_method_names listesini genişletin, FastAPI route'larında QUERY'yi açıkça listeleyin ve nginx yapılandırmalarında limit_except için grep çalıştırın; Caddy ve Traefik ise hiçbir şey gerektirmiyor. RFC'nin eski araçlar hakkındaki belirsiz uyarısı, bu örneklemde genel bir engel değil, iki spesifik ve düzeltilebilir red anlamına geliyor.

  • #nginx
  • #http
  • #django
  • #fastapi
  • #web-servers