वेब ऐप्स में सुरक्षित फ़ाइल अपलोड के लिए कठोर अनुमतियाँ, आकार सीमाएँ, साइन किए गए URLs और सरल मैलवेयर स्कैनिंग पैटर्न आवश्यक होते हैं ताकि घटनाओं से बचा जा सके।

फ़ाइल अपलोड सामान्य दिखते हैं: एक प्रोफ़ाइल फ़ोटो, एक PDF, एक स्प्रेडशीट। पर वे अक्सर पहली सुरक्षा घटना बनते हैं क्योंकि वे अजनबियों को आपके सिस्टम में एक रहस्यमय बॉक्स भेजने देते हैं। अगर आप उसे स्वीकार करते हैं, स्टोर करते हैं, और दूसरों को दिखाते हैं, तो आपने अपने ऐप पर एक नया हमला का तरीका बनाया।
जोखिम सिर्फ "किसी ने वायरस अपलोड किया" तक सीमित नहीं है। एक खराब अपलोड निजी फ़ाइलें लीक कर सकता है, आपका स्टोरेज बिल फाड़ सकता है, या उपयोगकर्ताओं को एक्सेस सौंपने में छल करवा सकता है। invoice.pdf नाम की फ़ाइल ज़रूरी नहीं कि PDF ही हो। यहाँ तक कि असली PDFs और इमेजेस भी परेशानी कर सकती हैं अगर आपका ऐप मेटाडेटा पर भरोसा करता है, स्वचालित रूप से प्रीव्यू बनाता है, या उन्हें गलत नियमों के साथ सर्व करता है।
असल विफलताएँ आमतौर पर इस तरह दिखती हैं:
एक बात कई घटनाओं को जन्म देती है: फ़ाइलों को स्टोर करना और उन्हें सर्व करना एक ही चीज़ नहीं है। स्टोरेज वह जगह है जहाँ आप बाइट्स रखते हैं। सर्विंग वह तरीका है जिससे वे ब्राउज़र और ऐप्स तक पहुँचते हैं। चीजें तब बिगड़ती हैं जब कोई ऐप यूज़र अपलोड्स को उसी भरोसे और नियमों के साथ सर्व करता है जैसे मुख्य वेबसाइट, तो ब्राउज़र उस अपलोड को “ट्रस्टेड” मान लेता है।
छोटे या बढ़ते हुए ऐप के लिए "पर्याप्त सुरक्षित" का मतलब अक्सर यह है कि आप चार सवाल बिना बहाने के जवाब दे सकें: कौन अपलोड कर सकता है, आप क्या स्वीकार करते हैं, कितना बड़ा और कितनी बार, और बाद में कौन पढ़ सकता है। भले ही आप तेजी से बना रहे हों, ये गार्डरेल्स ज़रूरी हैं।
हर अपलोड को अनट्रस्टेड इनपुट समझें। अपलोड्स को सुरक्षित रखने का व्यावहारिक तरीका यह है कि आप यह सोचें कि कौन इसका दुरुपयोग कर सकता है और उनके लिए “सफलता” क्या होगी।
अधिकतर अटैकर या तो कमजोर अपलोड फ़ॉर्म्स स्कैन करने वाले बॉट होते हैं या असली उपयोगकर्ता जो मुफ्त स्टोरेज पाने, डेटा स्क्रेप करने, या आपकी सेवा को ट्रोल करने की कोशिश कर रहे होते हैं। कभी-कभी यह प्रतियोगी भी होते हैं जो लीक या आउटेज के लिए probing कर रहे हों।
वे क्या चाहते हैं? आमतौर पर इनमें से एक परिणाम:
फिर कमजोरियों को मैप करें। अपलोड एंडपॉइंट है फ्रंट डोर (ओवरसाइज़्ड फाइलें, अजीब फॉर्मैट, हाई रिक्वेस्ट रेट)। स्टोरेज है बैक रूम (पब्लिक बकेट, गलत अनुमतियाँ, साझा फोल्डर)। डाउनलोड URLs हैं निकास (अनुमान लगाने योग्य, लंबे समय तक चलने वाले, या किसी उपयोगकर्ता से न जुड़े हुए)।
उदाहरण: एक “resume upload” फीचर। एक बॉट हजारों बड़ी PDFs अपलोड कर लागत बढ़ा सकता है, जबकि एक दुरुपयोगी उपयोगकर्ता HTML फ़ाइल अपलोड करके उसे एक “डॉक्यूमेंट” की तरह साझा कर दूसरों को धोखा दे सकता है।
नियंत्रण जोड़ने से पहले तय कर लें कि आपके ऐप के लिए क्या सबसे महत्वपूर्ण है: गोपनीयता (कौन पढ़ सकता है), उपलब्धता (क्या आप सर्व कर पाएँगे), लागत (स्टोरेज और बैंडविड्थ), और अनुपालन (डेटा कहाँ रखा जाता है और कितनी देर रखना है)। यही प्राथमिकता सूची निर्णयों को संगत रखती है।
अधिकांश अपलोड घटनाएँ बड़ी हैक नहीं होतीं। वे सरल “मैं किसी और की फ़ाइल देख सकता हूँ” बग होती हैं। अपलोड्स को अनुमति के हिस्से के रूप में संभालें, न कि बाद में जोड़ी गई फीचर के रूप में।
एक नियम से शुरू करें: डिफ़ॉल्ट डिनाय। हर अपलोड किए गए ऑब्जेक्ट को प्राइवेट मानें जब तक कि आप स्पष्ट रूप से एक्सेस न दें। "डिफ़ॉल्ट प्राइवेट" इनवॉइस, मेडिकल फ़ाइलें, अकाउंट डॉक्यूमेंट्स और किसी भी यूज़र-टाईड डेटा के लिए मजबूत बेसलाइन है। फ़ाइलों को तभी सार्वजनिक बनाएं जब उपयोगकर्ता स्पष्ट रूप से उम्मीद करे (जैसे सार्वजनिक अवतार), और तब भी समय-सीमित एक्सेस पर विचार करें।
रोल्स को सरल और अलग रखें। एक सामान्य विभाजन है:
"/user-uploads/" जैसी फोल्डर-स्तरीय नियमों पर भरोसा न करें। हर फ़ाइल पढ़ने पर मालिकाना हक या टेनेट एक्सेस जांचें। यह तब भी सुरक्षित रखता है जब कोई टीम बदलता है, कोई ऑर्ग छोड़ता है, या फ़ाइल फिर असाइन की जाती है।
एक अच्छा सपोर्ट पैटर्न संकुचित और अस्थायी होता है: एक विशिष्ट फ़ाइल के लिए एक्सेस दें, उसे लॉग करें, और ऑटोमैटिक रूप से एक्सपायर कर दें।
अधिकतर अपलोड हमले सरल चाल से शुरू होते हैं: एक फ़ाइल जो नाम या ब्राउज़र हेडर की वजह से सुरक्षित दिखती है, पर असल में कुछ और होती है। क्लाइंट द्वारा भेजी हर चीज़ को अनट्रस्टेड माने।
एक allowlist से शुरू करें: ठीक-ठीक फॉर्मैट तय करें जिन्हें आप स्वीकार करते हैं (उदाहरण के लिए .jpg, .png, .pdf) और बाकी सब reject कर दें। "कोई भी इमेज" या "कोई भी डॉक्यूमेंट" तभी रखें जब सचमुच ज़रुरत हो।
फ़ाइलनाम एक्सटेंशन या क्लाइंट का Content-Type हैडर मत मानो। दोनों आसानी से नकली हो सकते हैं। invoice.pdf नाम की फ़ाइल एक executable भी हो सकती है, और Content-Type: image/png झूठ हो सकता है।
मजबूत तरीका है फ़ाइल के पहले बाइट्स की जाँच, जिन्हें अक्सर “magic bytes” या फाइल सिग्नेचर कहा जाता है। कई सामान्य फॉर्मैट्स के पास स्थिर हेडर होते हैं (जैसे PNG और JPEG)। अगर हेडर आपकी allowlist से मेल नहीं खाता, तो रिजेक्ट करें।
व्यवहारिक वैलिडेशन सेटअप:
नाम बदलना जितना लगता है उससे ज़्यादा मायने रखता है। अगर आप यूज़र-प्रदान नाम सीधे स्टोर करते हैं तो पाथ ट्रिक्स, अजीब कैरेक्टर्स, और आकस्मिक ओवरराइट्स के लिए दरवाज़ा खोलते हैं। स्टोरेज के लिए जनरेटेड ID का उपयोग करें और असली फ़ाइलनाम केवल डिस्प्ले के लिए रखें।
प्रोफ़ाइल फ़ोटो के लिए केवल JPEG और PNG स्वीकार करें, हेडर सत्यापित करें, और मुमकिन हो तो मेटाडेटा हटाएं। डॉक्यूमेंट्स के लिए PDF तक सीमित करने पर विचार करें और किसी भी सक्रिय कंटेंट को अस्वीकार करें। अगर बाद में SVG या HTML की ज़रूरत पड़े, तो उन्हें संभावित तौर पर executable मानकर अलग रखें।
अधिकांश अपलोड आउटेज "शानदार हैकर" की वजह से नहीं होते—वे बहुत बड़ी फाइलें, बहुत सारे अनुरोध, या धीमी कनेक्शन जो सर्वर्स को बांध देती हैं की वजह से होते हैं। हर बाइट को एक लागत मानें।
हर फ़ीचर के लिए अधिकतम आकार चुनें, न कि एक ग्लोबल नंबर। एक अवतार को टैक्स डॉक्यूमेंट या छोटे वीडियो जितनी जरूरत नहीं होती। सबसे छोटा लिमिट रखें जो सामान्य लगे, और बड़ी फाइलों के लिए अलग "लार्ज अपलोड" मार्ग रखें (जैसे सigned URL के साथ डायरेक्ट-टू-ऑब्जेक्ट-स्टोरेज)।
क्लाइंट झूठ बोल सकता है इसलिए सीमाएँ कई जगह लागू करें: ऐप लॉजिक में, वेब सर्वर या रिवर्स प्रॉक्सी पर, अपलोड टाइमआउट्स के साथ, और घोषित साइज़ बहुत बड़ी होने पर पहले से इंकार करके (पूरे बॉडी को पढ़ने से पहले)।
ठोस उदाहरण: अवतार 2 MB पर कैप, PDFs 20 MB पर कैप, और इससे बड़ी किसी भी चीज के लिए अलग फ्लो चाहिए।
छोटे फ़ाइल भी तभी DoS बन सकते हैं जब कोई उन्हें लूप में बार-बार अपलोड करे। अपलोड एंडपॉइंट्स पर प्रति-यूज़र और प्रति-IP रेट लिमिट लगाएँ। अनऑथ ट्रैफिक के लिए सख्त सीमाएँ रखें।
रिज्यूमेबल अपलोड असली उपयोगकर्ताओं के लिए मददगार हैं, पर सेशन टोकन को सख्त रखें: छोटा एक्सपायरी, उपयोगकर्ता से बांधा हुआ, और विशिष्ट फ़ाइल साइज़ व डेस्टिनेशन से बाँधा हुआ। वरना "resume" एंडपॉइंट्स स्टोरेज में मुफ्त पाइप बन सकते हैं।
जब आप अपलोड ब्लॉक करें तो उपयोगकर्ता के लिए स्पष्ट त्रुटि लौटाएँ (फ़ाइल बहुत बड़ी, बहुत अधिक अनुरोध) पर आंतरिक जानकारी (स्टैक ट्रेस, बकेट नाम, वेंडर विवरण) न लीक करें।
सुरक्षित अपलोड्स केवल इस बारे में नहीं कि आप क्या स्वीकार करते हैं। यह भी मायने रखता है कि फ़ाइल कहाँ जाती है और आप उसे बाद में कैसे वापस देते हैं।
अपलोड बाइट्स को अपने मुख्य डेटाबेस से बाहर रखें। अधिकांश ऐप्स को केवल मेटाडेटा DB में चाहिए (owner user ID, original filename, detected type, size, checksum, storage key, created time)। बाइट्स को object storage या बड़े ब्लॉब्स के लिए बने फ़ाइल सर्विस में रखें।
पब्लिक और प्राइवेट फाइल्स को स्टोरेज स्तर पर अलग रखें। अलग बकेट या कंटेनर का उपयोग करें जिनके अलग नियम हों। सार्वजनिक फ़ाइलें (जैसे सार्वजनिक अवतार) बिना लॉगिन के पढ़ी जा सकती हैं। निजी फ़ाइलें (कॉन्ट्रैक्ट, इनवॉइस, मेडिकल डॉक्यूमेंट) कभी भी पब्लिक-रीडेबल नहीं होनी चाहिए, भले ही कोई URL अनुमान लगा ले।
जब संभव हो तो यूज़र फ़ाइलों को उसी डोमेन से सर्व करने से बचें जिस पर आपका ऐप चलता है। अगर कोई जोखिम भरी फ़ाइल स्लिप हो जाती है (HTML, SVG जिनमें स्क्रिप्ट हो, या ब्राउज़र MIME स्निफिंग की अनोखी स्थितियाँ), तो उसे आपके मुख्य डोमेन पर होस्ट करने से अकाउंट टेकओवर तक का जोखिम बढ़ सकता है। एक अलग डाउनलोड डोमेन (या स्टोरेज डोमेन) ब्लास्ट रेडियस को सीमित करता है।
डाउनलोड पर सुरक्षित हेडर्स मजबूर करें। Content-Type को उस चीज़ पर सेट करें जो आप अनुमति देते हैं, न कि जो उपयोगकर्ता ने दावा किया। किसी भी चीज़ के लिए जिसे ब्राउज़र इंटरप्रेट कर सकता है, डाउनलोड भेजना बेहतर है।
कुछ डिफ़ॉल्ट जो आश्चर्य रोकते हैं:
Content-Disposition: attachment उपयोग करें।Content-Type (या application/octet-stream) रखें।रिटेंशन भी सुरक्षा है। परित्यक्त अपलोड्स हटाएँ, रिप्लेसमेंट के बाद पुराने वर्ज़न हटाएँ, और अस्थायी फ़ाइलों के लिए समय सीमाएँ सेट करें। कम स्टोर किया डेटा, कम लीक होने की संभावनाएँ।
Signed URLs (अक्सर pre-signed URLs भी कहा जाता है) एक आम तरीका हैं जिससे आप उपयोगकर्ताओं को स्टोरेज बकेट पब्लिक किए बिना अपलोड/डाउनलोड करने दे सकते हैं, और बिना हर बाइट को अपनी API से भेजे। URL अस्थायी अनुमति साथ आता है, फिर एक्सपायर हो जाता है।
दो सामान्य फ्लो:
Direct-to-storage API लोड कम करता है, पर यह स्टोरेज नियमों और URL constraints को और महत्वपूर्ण बनाता है।
एक signed URL को एक-टाइम की चाबी समझें। इसे विशिष्ट और छोटा रखें।
व्यवहारिक पैटर्न: पहले एक अपलोड रिकॉर्ड बनाएं (status: pending), फिर signed URL जारी करें। अपलोड के बाद पुष्टि करें कि ऑब्जेक्ट मौजूद है और अपेक्षित साइज़ व टाइप मैच करते हैं, तब status को ready/available मार्क करें।
एक सुरक्षित अपलोड फ्लो ज्यादातर स्पष्ट नियम और स्पष्ट स्टेट्स है। हर अपलोड को अनचेकेड मानें जब तक जाँच पूरी न हो।
लिखित लिखें कि प्रत्येक फीचर क्या अनुमति देता है। प्रोफ़ाइल फ़ोटो और टैक्स डॉक्यूमेंट को एक ही फ़ाइल प्रकार, साइज़ लिमिट, या दृश्यता साझा नहीं करनी चाहिए।
अनुमति दिए गए प्रकार और प्रति-फ़ीचर आकार सीमा परिभाषित करें (उदा.: फ़ोटो 5 MB तक; PDFs 20 MB तक)। इन्हें बैकएंड में लागू करें।
बाइट्स आने से पहले एक "upload record" बनाएं। स्टोर करें: owner (user या org), purpose (avatar, invoice, attachment), original filename, expected max size, और pending जैसा स्टेटस।
अपलोड को एक प्राइवेट लोकेशन में रखें। क्लाइंट को अंतिम पाथ चुनने न दें।
सर्वर-साइड फिर से वैलिडेट करें: साइज़, magic bytes/टाइप, allowlist। अगर पास हो, तो स्टेटस uploaded में बदलें।
मैलवेयर स्कैन करें और स्टेटस को clean या quarantined में अपडेट करें। अगर स्कैन async है, तो एक्सेस तब तक लॉक रखें जब तक स्कैन पूरा न हो।
तभी डाउनलोड, प्रीव्यू, या प्रोसेसिंग की अनुमति दें जब स्टेटस clean हो।
एक छोटा उदाहरण: प्रोफ़ाइल फोटो के लिए, user से जुड़ा avatar प्रयोजन वाला रिकॉर्ड बनाएं, प्राइवेट रूप से स्टोर करें, पुष्टि करें कि यह वाकई JPEG/PNG है (सिर्फ नाम देखकर नहीं), स्कैन करें, फिर प्रीव्यू URL जेनरेट करें।
मैलवेयर स्कैनिंग एक सेफ़्टी नेट है, गारंटी नहीं। यह जाने-पहचाने खराब फ़ाइलों और स्पष्ट ट्रिक्स को पकड़ती है, पर हर चीज़ नहीं पकड़ पाएगी। लक्ष्य सरल है: जोखिम घटाना और अज्ञात फ़ाइलों को डिफ़ॉल्ट रूप से हानिरहित बनाना।
एक भरोसेमंद पैटर्न है: पहले क्वारंटीन। हर नए अपलोड को एक प्राइवेट, नॉन-पब्लिक लोकेशन में सेव करें और उसे pending मार्क करें। केवल जाँच पास होने पर उसे "clean" लोकेशन में मूव करें या उपलब्ध घोषित करें।
सिंक्रोनस स्कैन छोटे फ़ाइलों और कम ट्रैफ़िक के लिए काम करता है क्योंकि उपयोगकर्ता इंतज़ार करता है। अधिकांश ऐप्स स्कैनिंग को असिंक्रोनस करते हैं: अपलोड स्वीकार करें, "processing" स्टेट लौटाएँ, और बैकग्राउंड में स्कैन करें।
बेसिक स्कैनिंग में आम तौर पर एक एंटीवायरस इंजन (या सर्विस) और कुछ गार्डराइल्स होते हैं: AV स्कैन, फ़ाइल-टाइप चेक (magic bytes), आर्काइव लिमिट (zip bombs, nested zips, बहुत बड़ा अनकंप्रेस्ड साइज), और उन फॉर्मैट्स को ब्लॉक करना जिनकी आपको जरूरत नहीं है।
अगर स्कैन फेल हो, टाइमआउट हो, या "unknown" लौटे, तो फ़ाइल को संदिग्ध मानें। उसे क्वारंटाइन रखें और डाउनलोड लिंक न दें। यहाँ टीमें अक्सर झुलसती हैं: "scan failed" को कभी भी "फिर भी भेज दें" मत बनने दें।
जब आप फ़ाइल ब्लॉक करें तो संदेश न्यूट्रल रखें: "हम यह फ़ाइल स्वीकार नहीं कर सके। कोई अलग फ़ाइल आजमाएँ या सपोर्ट से संपर्क करें।" केवल तब कहें कि मैलवेयर मिला जब आप निश्चित हों।
मान लीजिए दो फीचर्स हैं: एक प्रोफ़ाइल फोटो (सार्वजनिक दिखता है) और एक PDF रसीद (निजी, बिलिंग/सपोर्ट के लिए)। दोनों अपलोड समस्याएँ हैं, पर उन्हें एक ही नियम साझा नहीं करने चाहिए।
प्रोफ़ाइल फोटो के लिए कड़ा नियम रखें: केवल JPEG/PNG की अनुमति दें, साइज़ कैप लगाएं (उदा. 2–5 MB), और सर्वर-साइड पर फिर से एन्कोड करें ताकि आप उपयोगकर्ता की ओरिजिनल बाइट्स सर्व न करें। चेक के बाद ही इसे पब्लिक स्टोरेज में रखें।
PDF रसीद के लिए बड़ी साइज स्वीकार करें (उदा. 20 MB), डिफ़ॉल्ट रूप से प्राइवेट रखें, और इसे अपने मुख्य ऐप डोमेन से inline में रेंडर न करें।
एक साधारण स्टेटस मॉडल उपयोगकर्ताओं को अंदरूनी बातों के बिना सूचित रखता है:
pending: उपयोगकर्ता ने फ़ाइल चुनी, अपलोड शुरू नहीं हुआuploaded: स्टोरेज ने बाइट्स प्राप्त कर लिएscanning: बैकग्राउंड जॉब इसे चेक कर रहा हैclean (या rejected): फ़ाइल उपलब्ध है (या ब्लॉक कर दी गई है)Signed URLs यहाँ अच्छी तरह फिट होते हैं: अपलोड के लिए छोटी-सी लाइफ वाली write-only signed URL का उपयोग करें (एक ऑब्जेक्ट कीज़ के लिए)। पढ़ने के लिए अलग, छोटी-सी लाइफ वाली signed URL जारी करें, और केवल जब status clean हो।
जांच के लिए जितनी ज़रूरत हो उतनी जानकारी लॉग करें, न कि फ़ाइल खुद: user ID, file ID, type guess, size, storage key, timestamps, scan result, request IDs। कच्चा कंटेंट या डॉक्यूमेंट के अंदर मिली संवेदनशील जानकारी लॉग न करें।
अधिकांश अपलोड बग इसलिए होते हैं क्योंकि एक छोटा "अस्थायी" शॉर्टकट स्थायी बन जाता है। मान लें हर फ़ाइल अनट्रस्टेड है, हर URL साझा किया जाएगा, और हर “हम बाद में ठीक करेंगे” सेटिंग भुला दी जाएगी।
बार-बार दिखने वाले जाल:
Content-Type के साथ सर्व करना, जिससे ब्राउज़र रिस्की कंटेंट को इंटरप्रेट कर ले।मॉनिटरिंग वह चीज़ है जिसे टीमें तब तक छोड़ देती हैं जब तक स्टोरेज बिल बढ़ न जाए। अपलोड वॉल्यूम, औसत साइज़, टॉप अपलोडर्स, और एरर रेट ट्रैक करें। एक समझौता अकाउंट रातों-रात हजारों बड़ी फ़ाइलें अपलोड कर सकता है।
उदाहरण: एक टीम अवतार्स को उपयोगकर्ता-प्रदान फ़ाइलनामों जैसे "avatar.png" के तहत shared फोल्डर में स्टोर करती है। एक उपयोगकर्ता दूसरे के इमेज को ओवरराइट कर देता है। उपाय साधारण पर प्रभावी है: सर्वर-साइड ऑब्जेक्ट कीज़ जेनरेट करें, अपलोड्स डिफ़ॉल्ट रूप से प्राइवेट रखें, और एक नियंत्रित रिस्पॉन्स के जरिए रीसाइज़्ड इमेज एक्सपोज़ करें।
इसे शिप करने से पहले अंतिम पास के रूप में उपयोग करें। प्रत्येक आइटम को एक रिलीज़ ब्लॉकर मानें, क्योंकि अधिकांश घटनाएँ एक छूटे हुए गार्डरेल से आती हैं।
Content-Type, सुरक्षित फ़ाइलनाम, और दस्तावेज़ों के लिए attachment।अपनी नीतियाँ साधारण भाषा में लिखें: स्वीकार्य प्रकार, अधिकतम साइज़, कौन क्या एक्सेस कर सकता है, signed URLs कितनी देर तक रहते हैं, और "scan passed" का क्या मतलब है। यह product, engineering, और support के बीच साझा अनुबंध बन जाता है।
कुछ ऐसे टेस्ट जोड़ें जो सामान्य विफलताओं को पकड़ें: ओवरसाइज़्ड फाइलें, नाम बदले गए executable, अनधिकृत पढ़ाई, एक्सपायरड signed URLs, और "scan pending" के दौरान डाउनलोड। ये टेस्ट किसी घटना की तुलना में सस्ते हैं।
अगर आप तेजी से बना और इटरेट कर रहे हैं, तो ऐसी वर्कफ़्लो उपयोगी होती है जहाँ बदलावों की योजना बनाकर उन्हें सुरक्षित तरीके से रोलबैक किया जा सके। टीमें Koder.ai (koder.ai) का उपयोग करते हुए अक्सर planning mode और snapshots/rollback पर निर्भर रहती हैं जब वे अपलोड नियम कड़े कर रहे होते हैं, पर मूल आवश्यकता वही रहती है: पॉलिसी बैकएंड द्वारा लागू हो, UI द्वारा नहीं।
सबसे पहले अपनाएँ: डिफ़ॉल्ट रूप से प्राइवेट रखें और हर अपलोड को अनट्रस्टेड इनपुट मानें। सर्वर-साइड चार बुनियादी चीज़ें लागू करें:
यदि आप इनका स्पष्ट उत्तर दे सकते हैं, तो आप अधिकांश घटनाओं से आगे हैं।
क्योंकि उपयोगकर्ता एक “मिस्ट्री बॉक्स” अपलोड कर सकते हैं जिसे आपका ऐप संग्रहीत करता है और बाद में दूसरों को दिखा सकता है। इससे हो सकता है:
यह ज़्यादातर सिर्फ "किसी ने वायरस अपलोड किया" नहीं होता।
संग्रह करना का अर्थ है बाइट्स को कहीं रखना। सर्व करना का अर्थ है उन बाइट्स को ब्राउज़र और ऐप्स तक पहुँचाना।
जो खतरा है वह तब पैदा होता है जब आपका ऐप यूज़र अपलोड को उसी भरोसे और नियमों के साथ सर्व करता है जैसे मुख्य साइट को। अगर कोई जोखिम भरी फ़ाइल सामान्य पेज जैसी ट्रीटेड हो, तो ब्राउज़र उसे निष्पादित कर सकता है (या उपयोगकर्ता उस पर बहुत भरोसा कर सकते हैं)।
सुरक्षित डिफ़ॉल्ट यह है: पहले प्राइवेट में रखो, फिर नियंत्रित डाउनलोड रिस्पॉन्स के जरिए सुरक्षित हेडर भेजो।
अपना नियम बनाएँ: डिफ़ॉल्ट डिनाय और हर बार फ़ाइल डाउनलोड/प्रिव्यू पर एक्सेस सत्यापित करें।
व्यवहारिक नियम:
अधिकांश असली बग सरल “मुझे किसी और की फ़ाइल दिख रही है” तरह के होते हैं।
फ़ाइल का नाम एक्सटेंशन या ब्राउज़र का Content-Type भरोसेमंद नहीं होता। सर्वर पर यह करें:
अगर बाइट्स अनुमति दिए गए फॉर्मैट से मैच नहीं करते, तो अपलोड रिजेक्ट करें।
क्योंकि आउटेज अक्सर बोरिंग दुरुपयोग से आते हैं: बहुत सारे अपलोड, विशाल फ़ाइलें, या धीमी कनेक्शन जो सर्वर्स को बांध देती हैं।
अच्छे डिफ़ॉल्ट:
हर बाइट को लागत समझें और हर अनुरोध को संभावित दुरुपयोग मानें।
हाँ, पर सावधानी के साथ। Signed URLs ब्राउज़र को सीधे स्टोरेज में अपलोड/डाउनलोड करने देते हैं बिना बकेट को पब्लिक किए।
अच्छे डिफ़ॉल्ट:
Direct-to-storage API लोड कम करता है, पर स्कोपिंग और एक्सपायरी जरूरी हैं।
सबसे सुरक्षित पैटर्न है:
pending स्थिति वाला अपलोड रिकॉर्ड बनाएंहां, स्कैनिंग मदद करती है, पर यह गारंटी नहीं है। इसे एक सेफ़्टी नेट समझें, अकेला नियंत्रण न मानें।
व्यवहारिक तरीका:
नीति महत्वपूर्ण है: “न स्कैन हुआ” का मतलब कभी “उपलब्ध” नहीं होना चाहिए।
फ़ाइलों को इस तरह सर्व करें कि ब्राउज़र उन्हें वेब पेज की तरह इंटरप्रेट न करे।
अच्छे डिफ़ॉल्ट:
Content-Disposition: attachment सेट करेंContent-Type (या application/octet-stream) उपयोग करेंclean या quarantined में बदलेंclean होयह सुनिश्चित करता है कि “स्कैन फ़ेल” या “प्रोसेसिंग” फ़ाइल गलती से साझा न हो सके।
इससे जोखिम कम होता है कि कोई अपलोड की हुई फ़ाइल फ़िशिंग पेज या स्क्रिप्ट निष्पादन बन जाए।