Cloudflare'ın bot-challenge sistemi, sıradan HTML form gönderimlerini sessizce engelleyebilir ve basit bir ödeme tıklamasını gerçek kullanıcılar için bir çıkmaza dönüştürebilir. İsteği yerel bir navigasyon POST işleminden fetch-öncelikli bir akışa geçirmek, güvenliği tehlikeye atmadan deneyimi geri kazandırır.
Sorun neden önemli
Bir geliştirici; her test paketinde, curl ile ve yerel sunucuda çalışan bir ödeme formu yayınladı. Aynı form, bir müşteri Chrome kullandığında, ilk tıklamadan sonra bir güvenlik hatası ve ikinci tıklamada bir “timeout-or-duplicate” mesajı verdi. Bu başarısızlık, üç acil düzeltme (hot-fix) sürümü ve tam bir günlük hata ayıklama sürecini zorunlu kıldı.
Gizli uç nokta (edge)
Form, düz bir HTML <form> öğesine dayanan açık kaynaklı bir Astro paketinde yer alıyor. Kullanıcı Pay butonuna tıkladığında, sunucu Stripe'a bir 303 yönlendirmesiyle yanıt veriyor ve tarayıcı herhangi bir JavaScript kullanmadan yönlendirmeyi takip ediyor. Siteler, betikler devre dışı bırakıldığında yedek plan olarak bu deseni kullanır.
Cloudflare sitenin önünde durur ve bir bot algılama motoru çalıştırır. Sıradan GET istekleri için ara bir doğrulama (bir CAPTCHA veya JavaScript kontrolü) gösterebilir. Tarayıcı doğrulamayı geçtikten sonra istek devam eder.
Ancak bir navigasyon POST işlemi, bir doğrulama için duraklatılamaz ve ardından gövdesi (body) bozulmadan devam ettirilemez. Edge, isteği atar ve 503 durumu döndürerek tarayıcıyı boş bir sayfa veya genel bir hata ile baş başa bırakır. Cloudflare'ın güvendiği aynı parmak izine sahip olan otomatik test tarayıcıları doğrulamayı asla tetiklemez, bu nedenle sorun gerçek bir kullanıcı siteye girene kadar görünmez kalır.
Günlükler (logs) neyi ortaya çıkardı
Bir kullanıcının Chrome oturumundan alınan canlı ağ izlemesi, aynı uç noktaya yapılan iki zıt isteği gösterdi:
- Navigation POST → 503 yanıtı, sekme dondu.
- fetch() POST → istek tamamlandı.
Her iki istek de aynı kökenden (origin) kaynaklanıyor, aynı kimlik bilgilerini taşıyor ve aynı anda gerçekleşiyordu. Tek fark taşıma yöntemiydi. fetch isteği, navigasyon POST işlemlerini engelleyen ara akışı (interstitial flow) atladı.
Hiçbir yere varmayan yollar
Geliştirici, kök nedeni kaçıran bir dizi düzeltme denedi:
- Sürelerinin dolduğunu varsayarak Turnstile jetonlarını (tokens) yeniledi.
- Engellemenin konum tabanlı olduğunu düşünerek IP aralıklarını beyaz listeye ekledi.
- Uzantıları devre dışı bıraktı, service worker'ları temizledi ve çerezleri sildi.
Her değişiklik hatayı değiştirmedi çünkü başarısızlık istemci veya sunucu kodunda değil, yukarı akıştaki (upstream) edge noktasında kaynaklanıyordu.
Pragmatik çözüm
Cloudflare'ın korumasını kapatmak yerine, form fetch-öncelikli bir desen kullanacak şekilde yeniden tasarlandı:
- Form verilerini toplayın ve bunları
fetch()ile bir JSON yükü (payload) olarak gönderin. - Sunucunun yanıtını işleyin. Eğer sunucu ödeme ağ geçidi için bir URL döndürürse, basit bir GET isteği ile oraya gitmek için
location.assign()işlevini çağırın.
fetch istekleri ara doğrulamayı tetiklemez, böylece POST isteği köken sunucuya (origin server) ulaşır. Sonraki GET yönlendirmesi, GET gövdeleri boş olduğu ve kullanıcı doğrulamayı geçtikten sonra tekrar oynatılabileceği için herhangi bir doğrulamadan güvenle geçebilir.
Geliştiriciler için riskler
- Kullanıcı güveni: Sessizce başarısız olan bir ödeme formu güveni sarsar ve gelir kaybına yol açabilir.
- Bakım yükü: Olay, üç yama sürümü ve tam bir günlük inceleme gerektirdi.
- Test kör noktaları: Yalnızca dahili test ortamlarına güvenmek, yalnızca gerçek dünyada ortaya çıkan uç durum (edge-case) hatalarını gözden kaçırabilir.
Daha geniş topluluk için dersler
- Gerçek tarayıcıları araçlandırın. Bir sorun yalnızca gerçek kullanıcılar için ortaya çıktığında, otomatik test çalışmalarına güvenmek yerine bu oturumlardan ağ günlüklerini yakalayın.
- Edge'i yığının (stack) bir parçası olarak kabul edin. Cloudflare, istemci ile sunucu arasında yer alır; davranışı isteklerin nasıl yapılandırılması gerektiğini etkiler.
- Doğru taşıma yöntemini seçin. Navigasyon POST'ları ve fetch POST'ları, edge noktasında farklı yollardan geçer. API'leri bu ayrımı göz önünde bulundurarak tasarlayın.
- Hata ayrıntılarını açığa çıkarın. Geliştiricilerin günlükleri derinlemesine incelemeden tam hata modunu görebilmeleri için 503 veya “timeout-or-duplicate” mesajlarını kullanıcı arayüzünde (UI) gösterin.
Bundan sonra neye dikkat edilmeli
Geliştiriciler, özellikle Cloudflare veya benzeri CDN güvenlik servisleri sitenin önünde duruyorsa, yerel POST navigasyonuna dayanan tüm form tabanlı iş akışlarını denetlemelidir. Hafif bir fetch sarmalayıcısı (wrapper) eklemek benzer hataları önceden engelleyebilir. Edge tarafından oluşturulan durum kodlarını yakalayan izleme araçları, sorunu müşterilere ulaşmadan önce işaretleyecektir.
Özet: Cloudflare'ın bot mücadeleleri aktif olduğunda, düz bir HTML form gönderimi sessiz hata (silent failure) riskine karşı savunmasızdır. POST işlemini fetch() üzerinden yeniden yönlendirmek ve akışı bir GET yönlendirmesiyle tamamlamak, güvenliği korurken edge kısıtlamasını aşmanızı sağlar. Edge'i sadece bir ağ sıçraması değil, bir kod olarak ele alın ve taşıma katmanlarınızı buna göre tasarlayın.
