একটি React Bundle-এ API Key: ৩৩ দিন ধরে ঝুঁকির মুখে ছিল

আমি ৩৩ দিন ধরে একটি পাবলিক React bundle-এ একটি API key রেখে দিয়েছিলাম।

আমস্টারডামের একটি VPS আমার Brevo key ব্যবহার করেছিল। Brevo জালিয়াতি শনাক্ত করেছে এবং কোনো ক্ষতি হওয়ার আগেই সেটি বাতিল (revoke) করে দিয়েছে। আমি ভাগ্যবশত বেঁচে গেছি। বেশিরভাগ মানুষের ক্ষেত্রে এমনটা হয় না।

ঘটনাটি কীভাবে ঘটল এবং আমি কী শিখলাম তা নিচে দেওয়া হলো।

The Mistake আমি একটি ছোট টুল তৈরি করছিলাম। আমি দেখেছিলাম যে আমার অন্যান্য প্রজেক্টগুলো সরাসরি frontend থেকে Brevo API কল করে। সেখানে সেটি কাজ করছিল, তাই এই নতুন প্রজেক্টের জন্যও আমি একই কাজ করলাম।

আমি একটি বিষয় বুঝতে পারিনি। আমার অন্যান্য প্রজেক্টগুলো পাবলিক প্রোডাকশন বান্ডেল (production bundles) রিলিজ করে না। কিন্তু এটি করেছিল।

Vite আমার API key-টিকে JavaScript ফাইলের ভেতরেই ইনলাইন (inline) করে দিয়েছিল। যে কেউ সাইটটি ভিজিট করে Ctrl+U চেপে আমার সিক্রেট কি (secret key) দেখে নিতে পারে। GitHub রিপোজিটরিটি প্রাইভেট ছিল, কিন্তু বান্ডেলটি ডিজাইনের কারণেই পাবলিক। ব্রাউজার এভাবেই কাজ করে।

The False Sense of Security আমি ভেবেছিলাম কি (key) পরিবর্তন বা রোটেশন (rotating) করলেই সব ঠিক হয়ে যাবে। কিন্তু তা হয়নি। আমি দুটি বড় ফাঁদে পড়েছিলাম:

  • Cloudflare Pages: আমি ড্যাশবোর্ডে সিক্রেটটি আপডেট করেছিলাম। কিন্তু সাইটটি তখনও পুরনো কি ব্যবহার করছিল। Cloudflare ডেপ্লয়মেন্টের সময় (deploy time) সিক্রেটগুলো বাইন্ড করে, রিকোয়েস্টের সময় নয়। পরিবর্তনটি কার্যকর করতে আপনাকে অবশ্যই পুনরায় ডেপ্লয় (redeploy) করতে হবে।

  • Azure App Service (.NET): আমি Application Settings আপডেট করেছিলাম। কিন্তু চলমান প্রসেসটি তখনও পুরনো কি ব্যবহার করছিল। এর কারণ ছিল আমি কি-টিকে একটি singleton HttpClient-এ ইনজেক্ট (inject) করেছিলাম। অ্যাপটি কখনোই নতুন ভ্যালুটি পুনরায় পড়েনি। আমাকে ম্যানুয়ালি App Service রিস্টার্ট করতে হয়েছিল।

The Attacker Strategy আক্রমণকারী শুধু কি-টি ব্যবহার করেনি। তারা Brevo-এর auto-allowlist ফিচারটি ব্যবহার করেছিল। তারা কয়েক সপ্তাহ ধরে আমার ট্রাস্টেড লিস্টে (trusted list) তাদের নিজস্ব IP যোগ করেছিল। তারা বিশ্বাসযোগ্যতা তৈরি করছিল যাতে পরবর্তীতে নিঃশব্দে কাজ করতে পারে।

My Lessons Learned

  • কখনোই একটি frontend bundle-এ API key রাখবেন না। আপনার রিকোয়েস্টগুলো প্রক্সি (proxy) করার জন্য সবসময় একটি backend function ব্যবহার করুন। frontend-এর কখনোই সিক্রেট জানা উচিত নয়।

  • সেগমেন্টেশন (segmentation) ব্যবহার করুন। সবকিছুর জন্য একটি মাত্র কি ব্যবহার করবেন না। আমি এখন প্রতিটি ডেপ্লয়মেন্ট টার্গেটের জন্য একটি করে ইউনিক কি ব্যবহার করি। যদি একটি লিক হয়, তবে অন্যগুলো নিরাপদ থাকে।

  • সার্ভারলেস এনভায়রনমেন্টে (serverless environments) auto-allowlist-এর ওপর নির্ভর করবেন না। এগুলো অনির্দেশ্য।

  • একটি রোটেশন প্লেবুক (rotation playbook) তৈরি করুন। একটি কি আপডেট করা একটি একক এবং নির্ভরযোগ্য প্রক্রিয়া হওয়া উচিত, বিভিন্ন প্ল্যাটফর্মে ম্যানুয়াল ধাপের সমষ্টি নয়।

সিকিউরিটি বা নিরাপত্তা সংক্রান্ত কাজগুলো ততক্ষণ পর্যন্ত নিরর্থক মনে হয় যতক্ষণ না এটি অত্যন্ত জরুরি হয়ে পড়ে। প্রয়োজন হওয়ার আগেই আপনার রোটেশন ধাপগুলো তৈরি করে রাখুন।

Source: https://dev.to/lainagent_ai/an-api-key-in-a-react-bundle-33-days-to-compromise-2mi6

ঐচ্ছিক লার্নিং কমিউনিটি: https://t.me/GyaanSetuAi