Signed URLs खराब करणारा Tracking-Link Bug

जर एखादा बग फक्त सर्वात महत्त्वाच्या गोष्टी खराब करत असेल, तर तो धोकादायक ठरू शकतो.

मला mail-history मध्ये एक बग आढळला जो सामान्य लिंक्ससाठी उत्तम प्रकारे काम करतो, परंतु signed URLs साठी अपयशी ठरतो. यामुळे ईमेल व्हेरिफिकेशन लिंक्स आणि signed डाउनलोड लिंक्स खराब होतात. या अशा लिंक्स आहेत जिथे एक चुकीचे अक्षर देखील Laravel ला विनंती (request) नाकारण्यास भाग पाडते.

हे कसे घडले ते खालीलप्रमाणे आहे.

mail-history तुमच्या HTML मध्ये बदल करून ईमेल क्लिक्स ट्रॅक करते. हे प्रत्येक लिंकला प्रथम एका redirect endpoint मधून पाठवण्यासाठी बदल करते. हे endpoint क्लिक रेकॉर्ड करते आणि त्यानंतर वापरकर्त्याला वास्तविक गंतव्यस्थानावर (destination) पाठवते.

हे करण्यासाठी, सिस्टम मूळ URL ला ट्रॅकिंग लिंकमध्ये एन्क्रिप्ट (encrypt) करते.

समस्या तेव्हा सुरू होते जेव्हा सिस्टम रेंडर केलेल्या (rendered) HTML मधून URL काढते. कोड ईमेल बॉडी वाचण्यापूर्वीच, Laravel ने HTML ला आधीच escape केले असते. लिंकमधील ampersand (&) चे रूपांतर & मध्ये होते.

https://example.com/page सारखी सामान्य लिंक व्यवस्थित काम करते. त्यात कोणतेही ampersands नसतात.

परंतु signed URL असे दिसते: https://example.com/email/verify/1/abc?expires=123&signature=deadbeef

HTML मध्ये, ते असे होते: https://example.com/email/verify/1/abc?expires=123&signature=deadbeef

कोड त्या & स्ट्रिंगला एन्क्रिप्ट करतो. जेव्हा वापरकर्ता क्लिक करतो, तेव्हा सिस्टम त्याला डिक्रिप्ट करते आणि वापरकर्त्याला & असलेली URL पाठवते. Laravel सिग्नेचर व्हेरिफाय करण्याचा प्रयत्न करते, परंतु अक्षरे मूळ अक्षरांशी जुळत नसल्यामुळे सिग्नेचर फेल होते.

याचे निराकरण कोडच्या एका ओळीने होऊ शकते. URL एन्क्रिप्ट करण्यापूर्वी तुम्हाला HTML entities डिकोड करणे आवश्यक आहे.

$originalUrl = html_entity_decode($matches[2], ENT_QUOTES | ENT_HTML5);

यामुळे एन्क्रिप्शन होण्यापूर्वी & चे पुन्हा & मध्ये रूपांतर होते. डिक्रिप्ट केलेली लिंक आता मूळ signed URL शी byte for byte जुळते.

हे पुन्हा होऊ नये म्हणून मी एक टेस्ट देखील जोडली आहे. ही टेस्ट तपासते की डिक्रिप्ट केलेल्या URL मध्ये खरोखर & आहे की &.

भविष्यातील कोड क्लीनअप दरम्यान असे छोटे बदल सहज विसरले जाऊ शकतात. नेहमी अशी टेस्ट लिहा जी विशिष्ट त्रुटीचे (failure) नाव स्पष्ट करते.

तुमच्यासाठी धडे:

  • जर तुम्ही रेंडर केलेल्या HTML मधून डेटा काढत असाल, तर तो escape केलेला आहे असे समजा.
  • ब्राउझर तुमच्यासाठी escape केलेली अक्षरे दुरुस्त करेल. एन्क्रिप्शन आणि रिडायरेक्ट्स तसे करणार नाहीत.
  • एक-ओळीच्या फिक्सेसचे (fixes) संरक्षण करण्यासाठी टेस्ट्सचा वापर करा.

स्रोत: https://dev.to/nasrulhazim/the-tracking-link-bug-that-only-breaks-signed-urls-38c