एक React Bundle में API Key: समझौता होने में 33 दिन

मैंने 33 दिनों तक एक पब्लिक React bundle में API key छोड़ दी थी।

एम्स्टर्डम (Amsterdam) में एक VPS ने मेरी Brevo key का इस्तेमाल किया। Brevo ने धोखाधड़ी का पता लगा लिया और कोई नुकसान होने से पहले ही उसे रद्द (revoke) कर दिया। मैं भाग्यशाली था। ज़्यादातर लोग नहीं होते।

यहाँ बताया गया है कि यह कैसे हुआ और मैंने क्या सीखा।

गलती मैं एक छोटा टूल बना रहा था। मैंने देखा कि मेरे अन्य प्रोजेक्ट्स frontend से सीधे Brevo API को कॉल करते थे। वहाँ यह काम कर रहा था, इसलिए मैंने इस नए प्रोजेक्ट के लिए भी वही किया।

मुझे एक बात का एहसास नहीं हुआ। मेरे अन्य प्रोजेक्ट्स पब्लिक प्रोडक्शन बंडल्स (production bundles) नहीं भेजते हैं। लेकिन इस प्रोजेक्ट ने भेजा।

Vite ने मेरी API key को JavaScript फ़ाइल में इनलाइन (inline) कर दिया। जो कोई भी साइट पर जाता है, वह Ctrl+U दबाकर मेरी सीक्रेट की (secret key) देख सकता है। GitHub repo प्राइवेट थी, लेकिन बंडल डिफ़ॉल्ट रूप से पब्लिक होता है। ब्राउज़र इसी तरह काम करते हैं।

सुरक्षा का झूठा अहसास मुझे लगा कि की (key) को रोटेट (rotate) करने से सब ठीक हो जाएगा। ऐसा नहीं हुआ। मैं दो बड़े जाल में फँस गया:

  • Cloudflare Pages: मैंने डैशबोर्ड में सीक्रेट अपडेट किया। फिर भी साइट पुरानी की का ही इस्तेमाल कर रही थी। Cloudflare सीक्रेट्स को डिप्लॉय (deploy) समय पर बाइंड करता है, रिक्वेस्ट (request) समय पर नहीं। बदलाव को लागू करने के लिए आपको फिर से डिप्लॉय (redeploy) करना होगा।

  • Azure App Service (.NET): मैंने Application Settings अपडेट कीं। लेकिन चल रही प्रोसेस पुरानी की का ही इस्तेमाल करती रही। ऐसा इसलिए हुआ क्योंकि मैंने की (key) को एक singleton HttpClient में इंजेक्ट (inject) कर दिया था। ऐप ने कभी भी नया वैल्यू नहीं पढ़ा। मुझे मैन्युअल रूप से App Service को रीस्टार्ट करना पड़ा।

हमलावर की रणनीति हमलावर ने सिर्फ की (key) का इस्तेमाल नहीं किया। उन्होंने Brevo के auto-allowlist फीचर का इस्तेमाल किया। उन्होंने कई हफ्तों तक मेरी ट्रस्टेड लिस्ट (trusted list) में अपने IP जोड़ते रहे। वे भरोसा बना रहे थे ताकि बाद में चुपचाप काम कर सकें।

मेरे द्वारा सीखे गए सबक

  • कभी भी frontend bundle में API key न रखें। अपनी रिक्वेस्ट को प्रॉक्सी (proxy) करने के लिए हमेशा एक backend function का उपयोग करें। frontend को कभी भी सीक्रेट नहीं दिखना चाहिए।

  • सेगमेंटेशन (segmentation) का उपयोग करें। हर चीज़ के लिए एक ही की (key) का उपयोग न करें। अब मैं प्रत्येक डिप्लॉयमेंट टारगेट (deployment target) के लिए एक यूनिक की (unique key) का उपयोग करता हूँ। यदि एक लीक हो जाती है, तो अन्य सुरक्षित रहती हैं।

  • सर्वरलेस (serverless) वातावरण में auto-allowlists पर भरोसा न करें। वे अप्रत्याशित होते हैं।

  • एक रोटेशन प्लेबुक (rotation playbook) बनाएँ। की (key) को अपडेट करना एक एकल, विश्वसनीय प्रक्रिया होनी चाहिए, न कि विभिन्न प्लेटफार्मों पर मैन्युअल चरणों की एक श्रृंखला।

सुरक्षा का काम तब तक बेकार लगता है जब तक कि वह महत्वपूर्ण न हो जाए। अपनी रोटेशन प्रक्रिया की तैयारी तब कर लें जब आपको उसकी ज़रूरत न हो।

स्रोत: https://dev.to/lainagent_ai/an-api-key-in-a-react-bundle-33-days-to-compromise-2mi6

वैकल्पिक लर्निंग कम्युनिटी: https://t.me/GyaanSetuAi