TrendVidStream তাদের সম্পূর্ণ অথেন্টিকেশন স্ট্যাক একটি rotating-refresh-token সিস্টেমে স্থানান্তরিত করেছে, যা একটি চুরি হওয়া টোকেন পুনরায় ব্যবহার করা মাত্রই শনাক্ত করতে পারে। এই পরিবর্তনের ফলে ৩০ দিনের একটি JWT, যা আগে একজন আক্রমণকারীকে অবাধে চলাফেরা করার সুযোগ দিত, তা এখন একটি স্বল্পমেয়াদী ক্রেডেনশ্যালে পরিণত হয়েছে যা তাৎক্ষণিকভাবে অ্যাকাউন্ট লক করে দেয়।

একটি মাত্র নিরাপত্তা লঙ্ঘনের কারণে এই পরিবর্তন করতে বাধ্য হতে হয়েছে: একটি পার্টনার SDK একটি ৩০ দিনের JWT প্লেইন টেক্সট হিসেবে ক্যাশ করে রেখেছিল, একজন আক্রমণকারী সেটি সংগ্রহ করে অন্য দেশ থেকে পুনরায় ব্যবহার (replay) করেছিল, এবং একমাত্র প্রতিকার ছিল সাইনিং কী (signing key) রোটেশন করা—যে অপারেশনের ফলে প্রতিটি ব্যবহারকারীকে লগ আউট করতে হয়েছিল। এই ঘটনাটি কোম্পানির টোকেন সিকিউরিটিকে নতুন রূপ দিয়েছে এবং বর্তমানে এটি তাদের ভিডিও-স্ট্রিমিং সার্ভিস পরিচালনা করছে।

কেন পুরনো মডেলটি ব্যর্থ হয়েছিল

JWT (JSON Web Tokens) হলো সেলফ-কন্টেইনড, সাইন করা ব্লব যা একটি ডাটাবেস লুকআপ ছাড়াই সার্ভারকে একটি রিকোয়েস্ট যাচাই করতে সাহায্য করে। এই সুবিধাটির একটি বড় মূল্য রয়েছে: যদি একটি টোকেন কয়েক সপ্তাহ পর্যন্ত কার্যকর থাকে, তবে সেটি চুরি হলে একজন আক্রমণকারী কয়েক সপ্তাহ ধরে অ্যাক্সেস পেয়ে যেতে পারে। এই নিরাপত্তা লঙ্ঘনের ক্ষেত্রে, চুরি হওয়া টোকেনটি তার ৩০ দিনের মেয়াদ শেষ না হওয়া পর্যন্ত বৈধ ছিল কারণ এটিকে সময়ের আগে বাতিল করার কোনো উপায় ছিল না।

সাইনিং কী রোটেশন করা হলো সমস্ত টোকেন বাতিল করার একমাত্র গ্লোবাল উপায়, কিন্তু এটি প্রতিটি ব্যবহারকারীকে পুনরায় লগ ইন করতে বাধ্য করে, যা সার্ভিস বিঘ্নিত করে এবং ব্যবহারকারীর আস্থা কমিয়ে দেয়। ত্রুটিটি JWT-তে ছিল না, বরং একটি মাত্র দীর্ঘমেয়াদী ক্রেডেনশিয়ালের ওপর নির্ভর করার মধ্যে ছিল।

নতুন ডিজাইনের সারসংক্ষেপ

TrendVidStream এখন দুই ধরনের টোকেন ইস্যু করে:

  • Access tokens – ১৫ মিনিটের জন্য কার্যকর; এগুলো প্রতিটি API কলের জন্য প্রয়োজনীয় পারমিশন বহন করে।
  • Refresh tokens – সিঙ্গেল-ইউজ টোকেন যা একটি স্বল্পমেয়াদী অ্যাক্সেস টোকেনের বিনিময়ে নতুন একটি জোড়া (pair) প্রদান করে।

যখন কোনো ক্লায়েন্ট একটি রিফ্রেশ টোকেন উপস্থাপন করে, সার্ভার:

  1. টোকেনের সিগনেচার এবং ক্লেইমস (claims) যাচাই করে।
  2. টোকেনটি ইতিমধ্যে ব্যবহৃত হয়েছে কি না তা পরীক্ষা করে।
  3. যদি পরীক্ষা সফল হয়, তবে একটি সম্পূর্ণ নতুন রিফ্রেশ টোকেন এবং একটি নতুন ১৫ মিনিটের অ্যাক্সেস টোকেন ইস্যু করে।
  4. পুরনো রিফ্রেশ টোকেনটিকে 'ব্যবহৃত' (used) হিসেবে চিহ্নিত করে।

যদি ২ নম্বর ধাপটি ব্যর্থ হয়—অর্থাৎ একই টোকেন দ্বিতীয়বার দেখা দেয়—তবে সার্ভার এটিকে চুরির সংকেত হিসেবে গণ্য করে এবং সেই লগইন সেশনের সাথে যুক্ত টোকেনের পুরো “ফ্যামিলি” বা পরিবারটি বাতিল (revoke) করে দেয়। ফলে ভিকটিম এবং আক্রমণকারী উভয়কেই পুনরায় লগ ইন করতে হয়, যা নিরাপত্তা লঙ্ঘনের সময়কাল কমিয়ে দেয়।

টোকেন ফ্যামিলি ট্র্যাকিং করা

প্রতিটি টোকেনকে আলাদা রেকর্ড হিসেবে না দেখে, সিস্টেমটি সেগুলোকে একটি ফ্যামিলিতে গ্রুপ করে, যা একজন ব্যবহারকারী লগ ইন করার সময় শুরু হয়। প্রতিটি রোটেশন সেই ফ্যামিলির একটি নতুন সদস্য তৈরি করে। প্রোডাকশনে ব্যবহৃত SQLite স্কিমাটি নিচের বিষয়গুলো সংরক্ষণ করে:

  • family_id – পুরো সেশনের জন্য একটি স্থিতিশীল আইডেন্টিফায়ার।
  • token_id – প্রতিটি রিফ্রেশ টোকেনের জন্য একটি অনন্য আইডেন্টিফায়ার।
  • generation – ডিবাগিংয়ের জন্য একটি কাউন্টার।
  • used_at – টোকেনটি কখন রিডিম করা হয়েছে তার টাইমস্ট্যাম্প।
  • revoked – একটি ফ্ল্যাগ যা সেট করা হলে পুরো ফ্যামিলিটি নিষ্ক্রিয় হয়ে যায়।

যখন কোনো পুনরায় ব্যবহারের ঘটনা শনাক্ত করা হয়, তখন সেই family_id-এর জন্য revoked ফ্ল্যাগটি সেট করা হয়, যা তাৎক্ষণিকভাবে সেই কম্প্রোমাইজড সেশনের অন্তর্গত প্রতিটি টোকেনকে বাতিল করে দেয়। এটি একটি নিঃশব্দ হাইজ্যাককে একটি উচ্চ-সংকেত অ্যালার্টে (high-signal alert) পরিণত করে যা লগ-এ দেখা যায়।

সিস্টেমকে নির্ভরযোগ্য রাখার জন্য তিনটি ইমপ্লিমেন্টেশন নিয়ম

  1. প্রথমে সিগনেচার যাচাই করুন সার্ভার যদি সিগনেচার যাচাই করার আগে “আগে ব্যবহৃত হয়েছে কি না?” তা পরীক্ষা করে, তবে একজন আক্রমণকারী টোকেন আইডি অনুমান করে গণহারে রভোকেশন (mass revocations) ঘটাতে পারে। প্রথমে সত্যতা নিশ্চিত করা অপ্রয়োজনীয় ডিনায়াল-অফ-সার্ভিস (denial-of-service) অ্যাটাক প্রতিরোধ করে।

  2. একটি গ্রেস উইন্ডো (grace window) রাখুন মোবাইল অ্যাপগুলো প্রায়ই টোকেন এক্সপায়ার হলে খুব দ্রুত পরপর দুটি রিফ্রেশ রিকোয়েস্ট পাঠায়। সার্ভার যদি খুব বেশি কঠোর হয়, তবে দ্বিতীয় রিকোয়েস্টটিকে পুনরায় ব্যবহার হিসেবে চিহ্নিত করা হবে, যা একজন বৈধ ব্যবহারকারীকে লগ আউট করে দেবে। কয়েক সেকেন্ডের একটি বাফার বা অতিরিক্ত সময় থাকলে একটি “ব্যবহৃত” টোকেনও নতুন একটি জোড়া ফেরত দিতে পারে, যা রেস কন্ডিশন (race conditions) সামলাতে সাহায্য করে।

  3. পুরো ফ্লো-টিকে একটি ট্রানজ্যাকশনে রাখুন সাথে রো-লকিং (row locking) অ্যাটমিসিটি (atomicity) ছাড়া, দুটি সমান্তরাল রিকোয়েস্ট উভয়ই ভাবতে পারে যে তারা প্রথমবার টোকেনটি ব্যবহার করছে, যার ফলে ডুপ্লিকেট রিফ্রেশ টোকেন ইস্যু হতে পারে এবং সিঙ্গেল-ইউজ গ্যারান্টি ভেঙে যেতে পারে। একটি ডাটাবেস ট্রানজ্যাকশন যা টোকেন রো-টিকে লক করে রাখে, তা নিশ্চিত করে যে কেবল একটি রিকোয়েস্ট সফল হবে।

মূল কথা: রিফ্রেশ টোকেনগুলোকে সিঙ্গেল-ইউজ হিসেবে ব্যবহার করে এবং পুনরায় ব্যবহারের দিকে নজর দিয়ে, একটি সিস্টেম প্রতিটি চুরি হওয়া ক্রেডেনশিয়ালকে একটি অ্যালার্মে পরিণত করতে পারে, যা প্ল্যাটফর্ম-ব্যাপী লগ আউট না করেই ব্যবহারকারীদের সুরক্ষা দেয়।