Cloudflare ची bot-challenge प्रणाली सामान्य HTML फॉर्म सबमिशन (submissions) शांतपणे थांबवू शकते, ज्यामुळे साध्या पेमेंट क्लिकचे रूपांतर खऱ्या वापरकर्त्यांसाठी एका मृत टोकामध्ये (dead-end) होऊ शकते. विनंतीला (request) नेटिव्ह नेव्हिगेशन POST ऐवजी fetch-first फ्लोमध्ये बदलल्यामुळे सुरक्षा धोक्यात न आणता अनुभव पूर्ववत होतो.

ही समस्या का महत्त्वाची आहे

एका डेव्हलपरने एक पेमेंट फॉर्म रिलीज केला जो प्रत्येक टेस्ट सूटमध्ये, curl मध्ये आणि लोकल सर्व्हरवर व्यवस्थित काम करत होता. तोच फॉर्म जेव्हा ग्राहकाने Chrome वापरला, तेव्हा पहिल्या क्लिकनंतर सुरक्षा त्रुटी (security error) आणि दुसऱ्या क्लिकवर “timeout-or-duplicate” असा संदेश आला. या अपयशामुळे तीन वेळा हॉट-फिक्स (hot-fix) रिलीज करावे लागले आणि पूर्ण दिवस डीबगिंगमध्ये गेला.

लपलेला 'edge'

हा फॉर्म एका ओपन-सोर्स Astro पॅकेजमध्ये आहे जो साध्या HTML <form> एलिमेंटवर अवलंबून आहे. जेव्हा वापरकर्ता Pay वर क्लिक करतो, तेव्हा सर्व्हर Stripe कडे 303 रिडायरेक्टसह प्रतिसाद देतो आणि ब्राउझर कोणत्याही JavaScript शिवाय त्या रिडायरेक्टला फॉलो करतो. जेव्हा स्क्रिप्ट्स अक्षम (disabled) असतात, तेव्हा साइट्स हा पॅटर्न फॉलबॅक (fallback) म्हणून वापरतात.

Cloudflare साइटच्या समोर असते आणि बॉट-डिटेक्शन इंजिन चालवते. सामान्य GET विनंत्यांसाठी (requests) ती एक इंटरस्टिशियल चॅलेंज (एक CAPTCHA किंवा JavaScript चेक) दाखवू शकते. ब्राउझरने चॅलेंज पास केल्यानंतर, विनंती पुढे proceed होते.

मात्र, नेव्हिगेशन POST ला चॅलेंजसाठी थांबवता येत नाही आणि नंतर त्याच्या बॉडीसह (body) पुन्हा सुरू करता येत नाही. 'edge' ही विनंती काढून टाकते आणि 503 स्टेटस परत करते, ज्यामुळे ब्राउझरसमोर एक कोरा पृष्ठ किंवा सामान्य त्रुटी येते. ऑटोमेटेड टेस्ट ब्राउझर्स, ज्यांच्याकडे Cloudflare कडे विश्वासार्ह असलेले समान फिंगरप्रिंट असतात, ते कधीही चॅलेंज ट्रिगर करत नाहीत, त्यामुळे जोपर्यंत एखादा खरा वापरकर्ता साइटवर येत नाही, तोपर्यंत ही समस्या अदृश्य राहते.

लॉग्सनी काय उघड केले

वापरकर्त्याच्या Chrome सेशनमधील लाइव्ह नेटवर्क ट्रेसने एकाच एंडपॉइंटवर दोन परस्परविरोधी विनंत्या दाखवल्या:

  • Navigation POST → 503 प्रतिसाद, टॅब हँग झाला.
  • fetch() POST → विनंती पूर्ण झाली.

दोन्ही विनंत्या एकाच ओरिजिनमधून (origin) आल्या होत्या, त्यामध्ये समान क्रेडेंशियल्स (credentials) होते आणि त्या एकाच वेळी घडल्या होत्या. एकमेव फरक म्हणजे ट्रान्सपोर्ट पद्धत (transport method). fetch विनंतीने त्या इंटरस्टिशियल फ्लोला बायपास केले जे नेव्हिगेशन POSTs ब्लॉक करते.

कोठेही न पोहोचवणारे मार्ग

डेव्हलपरने मूळ कारण शोधण्यात अपयशी ठरलेले अनेक उपाय करून पाहिले:

  • Turnstile टोकन्स रिन्यू केले, असे गृहीत धरून की ते संपले आहेत.
  • IP रेंज व्हाईटलिस्ट केल्या, असे समजून की ब्लॉक लोकेशन-आधारित आहे.
  • एक्स्टेंशन्स अक्षम केले, सर्व्हिस वर्कर्स क्लिअर केले आणि कुकीज डिलीट केल्या.

प्रत्येक बदलामुळे त्रुटी तशीच राहिली कारण हे अपयश क्लायंट किंवा सर्व्हर कोडमध्ये नसून 'edge' वर (upstream) होते.

व्यावहारिक उपाय

Cloudflare चे संरक्षण बंद करण्याऐवजी, फॉर्मला fetch-first पॅटर्न वापरण्यासाठी पुन्हा इंजिनिअर करण्यात आले:

  1. फॉर्म डेटा गोळा करा आणि तो fetch() द्वारे JSON पेलोड म्हणून पाठवा.
  2. सर्व्हरच्या प्रतिसादाची हाताळणी करा. जर सर्व्हर पेमेंट गेटवेसाठी URL परत करत असेल, तर साध्या GET विनंतीसह तिथे नेव्हिगेट करण्यासाठी location.assign() वापरा.

Fetch विनंत्या इंटरस्टिशियल चॅलेंज ट्रिगर करत नाहीत, त्यामुळे POST ओरिजिन सर्व्हरपर्यंत पोहोचते. त्यानंतरचा GET रिडायरेक्ट सुरक्षितपणे कोणत्याही चॅलेंजमधून जाऊ शकतो, कारण GET बॉडीज रिकाम्या असतात आणि वापरकर्त्याने चॅलेंज पास केल्यानंतर त्या पुन्हा वापरता येतात.

डेव्हलपर्ससाठी धोके

  • User trust: एक पेमेंट फॉर्म जो शांतपणे फेल होतो, तो विश्वास कमी करतो आणि महसूल गमावण्यास कारणीभूत ठरू शकतो.
  • Maintenance overhead: या घटनेमुळे तीन पॅच रिलीज आणि तपासणीसाठी पूर्ण दिवस लागला.
  • Testing blind spots: केवळ अंतर्गत टेस्ट एन्व्हायरनमेंटवर अवलंबून राहिल्यामुळे अशा edge-case त्रुटी सुटू शकतात ज्या केवळ प्रत्यक्ष वापरामध्ये (in the wild) दिसून येतात.

व्यापक समुदायासाठी धडे

  • Instrument real browsers. जेव्हा समस्या केवळ प्रत्यक्ष वापरकर्त्यांसाठी येते, तेव्हा ऑटोमेटेड टेस्ट रनवर विश्वास ठेवण्याऐवजी त्या सेशनमधील नेटवर्क लॉग्स कॅप्चर करा.
  • Treat the edge as part of the stack. Cloudflare क्लायंट आणि सर्व्हरच्या मध्ये असते; त्याचे वर्तन विनंत्या कशा प्रकारे स्ट्रक्चर केल्या पाहिजेत यावर परिणाम करते.
  • Choose the right transport. नेव्हिगेशन POSTs आणि fetch POSTs 'edge' वर वेगवेगळ्या मार्गांनी प्रवास करतात. हे अंतर लक्षात घेऊन API डिझाइन करा.
  • Expose error details. 503 किंवा “timeout-or-duplicate” संदेश UI वर दाखवा जेणेकरून डेव्हलपर्स लॉग्समध्ये शोध न घेता नेमकी त्रुटी पाहू शकतील.

पुढे काय पाहावे

डेव्हलपर्सनी नेटिव्ह POST नेव्हिगेशनवर अवलंबून असलेल्या कोणत्याही फॉर्म-आधारित वर्कफ्लोचे ऑडिट केले पाहिजे, विशेषतः जेव्हा Cloudflare किंवा तत्सम CDN सुरक्षा सेवा साइटच्या समोर असतात. हलका (lightweight) fetch wrapper जोडल्याने अशा प्रकारच्या त्रुटी टाळता येतील. edge-generated स्टेटस कोड्स कॅप्चर करणारी मॉनिटरिंग टूल्स ही समस्या ग्राहकांपर्यंत पोहोचण्यापूर्वीच सूचित करू शकतील.

मुख्य निष्कर्ष: जेव्हा Cloudflare चे बॉट चॅलेंजेस सक्रिय असतात, तेव्हा साध्या HTML फॉर्म सबमिशनमध्ये 'सायलेंट फेल्युअर' (silent failure) होण्याची शक्यता असते. fetch() द्वारे POST विनंती पुन्हा निर्देशित करणे आणि GET रिडायरेक्टद्वारे प्रक्रिया पूर्ण करणे, सुरक्षा कायम ठेवून एजच्या (edge) मर्यादा टाळते. एजला केवळ एक नेटवर्क हॉप न मानता कोड म्हणून पहा आणि त्यानुसार तुमचे ट्रान्सपोर्ट्स डिझाइन करा.