ট্র্যাকিং-লিঙ্ক বাগ যা সাইন্ড ইউআরএল (Signed URLs) নষ্ট করে দেয়
একটি বাগ তখনই বিপজ্জনক হতে পারে যখন এটি শুধুমাত্র সবচেয়ে গুরুত্বপূর্ণ বিষয়গুলোকে নষ্ট করে দেয়।
আমি mail-history-তে একটি বাগ খুঁজে পেয়েছি যা সাধারণ লিঙ্কের ক্ষেত্রে নিখুঁতভাবে কাজ করে কিন্তু signed URLs-এর ক্ষেত্রে ব্যর্থ হয়। এটি ইমেল ভেরিফিকেশন লিঙ্ক এবং সাইন্ড ডাউনলোড লিঙ্কগুলোকে নষ্ট করে দেয়। এগুলো এমন লিঙ্ক যেখানে একটি ভুল ক্যারেক্টার বা অক্ষরও Laravel-কে রিকোয়েস্টটি প্রত্যাখ্যান করতে বাধ্য করে।
এটি যেভাবে ঘটেছে তা নিচে দেওয়া হলো।
mail-history আপনার HTML পুনরায় লিখে ইমেল ক্লিক ট্র্যাক করে। এটি প্রতিটি লিঙ্ককে এমনভাবে পরিবর্তন করে যাতে সেটি প্রথমে একটি রিডাইরেক্ট এন্ডপয়েন্টের (redirect endpoint) মাধ্যমে যায়। এই এন্ডপয়েন্টটি ক্লিকটি রেকর্ড করে এবং তারপর ব্যবহারকারীকে আসল গন্তব্যে পাঠিয়ে দেয়।
এটি করার জন্য, সিস্টেমটি আসল URL-টিকে একটি ট্র্যাকিং লিঙ্কে এনক্রিপ্ট করে।
সমস্যাটি শুরু হয় যখন সিস্টেম রেন্ডার করা HTML থেকে URL সংগ্রহ করে। কোডটি যখন ইমেল বডি পড়ে, ততক্ষণে Laravel ইতিমধ্যে HTML-টিকে এস্কেপ (escape) করে ফেলেছে। একটি লিঙ্কের ভেতরে থাকা অ্যাম্পারস্যান্ড (&) হয়ে যায় &।
https://example.com/page এর মতো একটি সাধারণ লিঙ্ক ঠিকঠাক কাজ করে। এতে কোনো অ্যাম্পারস্যান্ড নেই।
কিন্তু একটি 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-এর সাথে মিলে যায়।
এটি যাতে আর না ঘটে সেজন্য আমি একটি টেস্টও যোগ করেছি। টেস্টটি পরীক্ষা করে দেখে যে ডিক্রিপ্ট করা URL-এ আসল & আছে নাকি & আছে।
ভবিষ্যতে কোড ক্লিনআপ করার সময় এই ধরণের ছোট সমাধানগুলো হারিয়ে যাওয়ার সম্ভাবনা থাকে। সবসময় এমন একটি টেস্ট লিখুন যা নির্দিষ্ট ত্রুটি বা ফেইলিউরের নাম উল্লেখ করে।
আপনার জন্য শিক্ষা:
- যদি আপনি রেন্ডার করা HTML থেকে ডেটা সংগ্রহ করেন, তবে ধরে নিন যে এটি এস্কেপ করা আছে।
- ব্রাউজার আপনার জন্য এস্কেপ করা ক্যারেক্টারগুলো ঠিক করে দেবে। কিন্তু এনক্রিপশন এবং রিডাইরেক্ট তা করবে না।
- এক লাইনের সমাধানগুলোকে সুরক্ষিত রাখতে টেস্ট ব্যবহার করুন।
Source: https://dev.to/nasrulhazim/the-tracking-link-bug-that-only-breaks-signed-urls-38c
