Cloudflare کا bot-challenge سسٹم عام HTML فارم سبمیشنز کو خاموشی سے ناکام بنا سکتا ہے، جس سے ایک سادہ ادائیگی (payment) کا کلک حقیقی صارفین کے لیے ایک بند راستے میں بدل جاتا ہے۔ نیٹیو نیویگیشن POST کے بجائے fetch-first فلو پر منتقل ہونے سے سیکیورٹی سے سمجھوتہ کیے بغیر تجربہ بحال ہو جاتا ہے۔
یہ مسئلہ کیوں اہم ہے
ایک ڈویلپر نے ادائیگی کا ایک ایسا فارم ریلیز کیا جو ہر ٹیسٹ سویٹ (test suite)، curl، اور لوکل سرور پر کام کر رہا تھا۔ وہی فارم، جب کسی کسٹمر نے Chrome استعمال کیا، تو پہلے کلک کے بعد سیکیورٹی ایرر اور دوسرے پر "timeout-or-duplicate" کا پیغام دکھاتا تھا۔ اس ناکامی کی وجہ سے تین ہاٹ فکس (hot-fix) ریلیزز اور ڈی بگنگ (debugging) کے لیے پورا دن ضائع ہوا۔
چھپا ہوا 'edge'
یہ فارم ایک اوپن سورس Astro پیکیج میں موجود ہے جو ایک سادہ HTML <form> ایلیمنٹ پر انحصار کرتا ہے۔ جب صارف Pay پر کلک کرتا ہے، تو سرور Stripe پر 303 ری ڈائریکٹ (redirect) کے ساتھ جواب دیتا ہے، اور براؤزر بغیر کسی JavaScript کے اس ری ڈائریکٹ پر عمل کرتا ہے۔ سائٹس اس پیٹرن کو اس وقت بطور فال بیک (fallback) استعمال کرتی ہیں جب اسکرپٹس ڈس ایبل ہوں۔
Cloudflare سائٹ کے سامنے موجود ہوتا ہے اور ایک bot-detection انجن چلاتا ہے۔ عام GET درخواستوں کے لیے یہ ایک انٹرسٹیشل چیلنج (interstitial challenge) (جیسے CAPTCHA یا JavaScript چیک) دکھا سکتا ہے۔ براؤزر چیلنج پاس کرنے کے بعد، درخواست آگے بڑھتی ہے۔
تاہم، ایک navigation POST کو چیلنج کے لیے روکا نہیں جا سکتا اور پھر اس کی باڈی (body) کو برقرار رکھتے ہوئے دوبارہ شروع نہیں کیا جا سکتا۔ 'edge' اس درخواست کو مسترد کر دیتا ہے اور 503 اسٹیٹس واپس کرتا ہے، جس سے براؤزر کے پاس ایک خالی صفحہ یا عام ایرر رہ جاتا ہے۔ خودکار ٹیسٹ براؤزرز، جو وہی فنگر پرنٹ رکھتے ہیں جس پر Cloudflare بھروسہ کرتا ہے، کبھی چیلنج کو ٹرگر نہیں کرتے، اس لیے یہ مسئلہ تب تک نظر نہیں آتا جب تک کوئی حقیقی صارف سائٹ پر نہ آ جائے۔
لاگز (logs) نے کیا ظاہر کیا
صارف کے Chrome سیشن کے ایک لائیو نیٹ ورک ٹریس نے ایک ہی اینڈ پوائنٹ (endpoint) پر دو متضاد درخواستیں دکھائیں:
- Navigation POST → 503 response, tab hung.
- fetch() POST → request completed.
دونوں درخواستیں ایک ہی اوریجن (origin) سے شروع ہوئی تھیں، ایک ہی کریڈنشلز (credentials) کے ساتھ تھیں، اور ایک ہی لمحے پر ہوئیں۔ واحد فرق ٹرانسپورٹ میتھڈ (transport method) کا تھا۔ fetch درخواست نے اس انٹرسٹیشل فلو کو بائی پاس کر دیا جو navigation POSTs کو روکتا ہے۔
وہ راستے جو کہیں نہ پہنچے
ڈویلپر نے اصلاحات کا ایک سلسلہ آزمایا لیکن اصل وجہ تک نہ پہنچ سکا:
- Turnstile ٹوکنز کو ری نیو (renew) کیا، یہ سمجھتے ہوئے کہ وہ ایکسپائر ہو گئے ہیں۔
- IP رینجز کو وائٹ لسٹ (whitelist) کیا، یہ سوچ کر کہ بلاک لوکیشن کی بنیاد پر ہے۔
- ایکسٹینشنز کو ڈس ایبل کیا، سروس ورکرز کو کلیئر کیا، اور کوکیز کو ڈیلیٹ کیا۔
ہر تبدیلی کے باوجود ایرر میں کوئی فرق نہیں پڑا کیونکہ ناکامی کلائنٹ یا سرور کوڈ میں نہیں بلکہ 'edge' پر اوپر (upstream) سے شروع ہوئی تھی۔
عملی حل
Cloudflare کی پروٹیکشن کو بند کرنے کے بجائے، فارم کو fetch-first پیٹرن استعمال کرنے کے لیے دوبارہ ڈیزائن کیا گیا:
- فارم کا ڈیٹا اکٹھا کریں اور اسے
fetch()کے ذریعے JSON پے لوڈ (payload) کے طور پر بھیجیں۔ - سرور کے رسپانس کو ہینڈل کریں۔ اگر سرور پیمنٹ گیٹ وے کے لیے ایک URL واپس کرتا ہے، تو وہاں سادہ GET درخواست کے ساتھ جانے کے لیے
location.assign()کو کال کریں۔
Fetch درخواستیں انٹرسٹیشل چیلنج کو ٹرگر نہیں کرتی ہیں، اس لیے POST اصل سرور تک پہنچ جاتی ہے۔ اس کے بعد کی GET ری ڈائریکٹ کسی بھی چیلنج سے بحفاظت گزر سکتی ہے، کیونکہ GET باڈیز خالی ہوتی ہیں اور صارف کے چیلنج کلیئر کرنے کے بعد انہیں دوبارہ چلایا جا سکتا ہے۔
ڈویلپرز کے لیے خطرات
- صارف کا اعتماد: ایک ادائیگی کا فارم جو خاموشی سے ناکام ہو جاتا ہے، اعتماد کو کمزور کرتا ہے اور آمدنی کے نقصان کا باعث بن سکتا ہے۔
- مینٹیننس کا بوجھ: اس واقعے کے لیے تین پیچ ریلیزز اور تحقیقات کے لیے پورا دن درکار تھا۔
- ٹیسٹنگ کے اندھے کونے (blind spots): صرف اندرونی ٹیسٹ ماحول پر انحصار کرنے سے وہ کیسز مس ہو سکتے ہیں جو صرف حقیقی دنیا میں ظاہر ہوتے ہیں۔
وسیع تر کمیونٹی کے لیے اسباق
- حقیقی براؤزرز کا استعمال کریں۔ جب کوئی مسئلہ صرف اصل صارفین کے لیے ظاہر ہو، تو خودکار ٹیسٹ رنز پر بھروسہ کرنے کے بجائے ان سیشنز سے نیٹ ورک لاگز حاصل کریں۔
- ایڈج (edge) کو اسٹیک کا حصہ سمجھیں۔ Cloudflare کلائنٹ اور سرور کے درمیان ہوتا ہے؛ اس کا طرزِ عمل اس بات پر اثر انداز ہوتا ہے کہ درخواستوں کو کیسے ترتیب دیا جانا چاہیے۔
- درست ٹرانسپورٹ کا انتخاب کریں۔ Navigation POSTs اور fetch POSTs 'edge' پر مختلف راستوں سے گزرتے ہیں۔ APIs کو اس فرق کو ذہن میں رکھتے ہوئے ڈیزائن کریں۔
- ایرر کی تفصیلات ظاہر کریں۔ 503 یا "timeout-or-duplicate" کے پیغامات کو UI پر دکھائیں تاکہ ڈویلپرز لاگز میں تلاشی لینے کے بجائے اصل ناکامی کا طریقہ دیکھ سکیں۔
آگے کیا دیکھنا چاہیے
ڈویلپرز کو کسی بھی فارم پر مبنی ورک فلو کا آڈٹ کرنا چاہیے جو نیٹیو POST نیویگیشن پر انحصار کرتا ہے، خاص طور پر جب سائٹ کے سامنے Cloudflare یا اسی طرح کی CDN سیکیورٹی سروسز موجود ہوں۔ ایک ہلکا پھلکا fetch wrapper شامل کرنے سے اسی طرح کی ناکامیوں کو روکا جا سکتا ہے۔ مانیٹرنگ ٹولز جو edge سے پیدا ہونے والے اسٹیٹس کوڈز کو محفوظ کرتے ہیں، مسئلے کو صارفین تک پہنچنے سے پہلے ہی نشان دہی کر دیں گے۔
اہم نکتہ: جب Cloudflare کے بوٹ چیلنجز فعال ہوں، تو ایک سادہ HTML فارم سبمیشن خاموش ناکامی (silent failure) کا شکار ہو سکتی ہے۔ fetch() کے ذریعے POST کو دوبارہ روٹ کرنا اور GET ری ڈائریکٹ کے ساتھ اس عمل کو مکمل کرنا، سیکیورٹی کو برقرار رکھتے ہوئے ایڈج (edge) کی حد بندی سے بچنے کا طریقہ ہے۔ ایڈج کو محض ایک نیٹ ورک ہاپ کے طور پر نہیں بلکہ کوڈ کے طور پر سمجھیں، اور اسی کے مطابق اپنے ٹرانسپورٹس ڈیزائن کریں۔
