ওয়েব অ্যাপে নিরাপদ ফাইল আপলোডের জন্য কঠোর অনুমতি, সাইজ সীমা, সাইন করা URL ও মৌলিক ম্যালওয়্যার স্ক্যানিং প্যাটার্ন দরকার যাতে ইনসিডেন্ট এড়ানো যায়।

ফাইল আপলোড বেশ নিরদোষ দেখায়: একজনের প্রোফাইল ছবি, একটা PDF, একটি স্প্রেডশীট। কিন্তু এগুলো প্রায়ই প্রথম সিকিউরিটি ইনসিডেন্টের কারণ হয়ে থাকে, কারণ এতগুলো অচেনা লোক আপনার সিস্টেমে একটি ‘রহস্য বাক্স’ পাঠাতে পারে। আপনি এটাকে গ্রহণ করলে, সংরক্ষণ করলে এবং অন্যদের সামনে দেখালে, আপনি আপনার অ্যাপে আক্রমণের নতুন পথ খুলে দিয়েছেন।
ঝুঁকি কেবল “কেউ ভাইরাস আপলোড করেছে”—এটাই নয়। একটি খারাপ আপলোড গোপন ফাইল ফাঁস করতে পারে, আপনার স্টোরেজ বিলকে ভেঙে দিতে পারে, বা ব্যবহারকারীদেরকে প্রবেশাধিকার হস্তান্তর করার ফাঁদে ফেলতে পারে। একটি নেরবে রাখা নাম “invoice.pdf” আসলেই PDF নাও হতে পারে। এমনকি বাস্তব PDF ও ইমেজও সমস্যা করতে পারে যদি আপনার অ্যাপ মেটাডেটায় বিশ্বাস করে, স্বয়ংক্রিয়ভাবে প্রিভিউ করে, বা ভুল নিয়মে সার্ভ করে।
বাস্তব ব্যর্থতা সাধারণত এমনভাবে দেখা যায়:
একটি গুরুত্বপূর্ণ বিষয় অনেক ঘটনার জন্য তাত্পর্যপূর্ণ: ফাইল সংরক্ষণ করা মানে ফাইল সার্ভ করা নয়। স্টোরেজ হল যেখানে বাইট রাখা হয়। সার্ভ করা হল কিভাবে সেই বাইট ব্রাউজার ও অ্যাপে সরবরাহ করা হয়। সমস্যা তখনই হয় যখন কোনো অ্যাপ ইউজার আপলোডকে একই বিশ্বাস স্তর ও নিয়মে সার্ভ করে যেটা মূল ওয়েবসাইটে আছে, ফলে ব্রাউজার সেই আপলোডকে “ট্রাস্টেড” মনে করে।
ছোট বা বাড়তে থাকা অ্যাপের জন্য “পর্যাপ্ত নিরাপত্তা” সাধারণত চারটি প্রশ্নের পরিষ্কার উত্তর দেয়ার মতো: কে আপলোড করতে পারে, আপনি কী গ্রহণ করেন, কত বড় ও কত ঘন ঘন, এবং পরে কে এটি পড়তে পারে। দ্রুত তৈরি করলেও (জেনারেটেড কোড বা চ্যাট-চালিত প্ল্যাটফর্ম), এসব গার্ডরেলগুলো গুরুত্বপূর্ণ।
প্রতিটি আপলোডকে অনবিশ্বাসী ইনপুট হিসেবে বিবেচনা করুন। আপলোডগুলো নিরাপদ রাখার ব্যবহারিক উপায় হল ভাবা—কে এগুলোকে দুর্ব্যবহার করতে পারে এবং তাদের “সফলতা” কিরকম দেখায়।
অনেক আক্রমণকারী হয় বট যা দুর্বল আপলোড ফর্ম খোঁজে, বা রিয়েল ব্যবহারকারী যারা লিমিট টেস্ট করে ফ্রি স্টোরেজ পেতে, ডেটা স্ক্র্যাপ করতে বা সার্ভিসকে টরল করতে চেষ্টা করে। মাঝে মাঝে প্রতিদ্বন্দ্বী কেও থাকেন লিক বা আউটেজ খোঁজার জন্য।
তারা সাধারণত কি চায়? এগুলোর মধ্যে সাধারণত একটিঃ
তারপর দুর্বল স্থলগুলো ম্যাপ করুন। আপলোড এন্ডপয়েন্ট হলো সামনের দরজা (অতিরিক্ত আকার, অদ্ভুত ফরম্যাট, উচ্চ রিকোয়েস্ট রেট)। স্টোরেজ হলো পিছনের রুম (পাবলিক বালতি, ভুল অনুমতিসমূহ, শেয়ার্ড ফোল্ডার)। ডাউনলোড URL হলো এক্সিট (পূর্বানুমানযোগ্য, দীর্ঘজীবী, বা ব্যবহারকারীর সাথে না বেঁধে থাকা)।
উদাহরণ: “রিজিউম আপলোড” ফিচার। একটি বট হাজার হাজার বড় PDF আপলোড করে খরচ বাড়ায়, আর একটি বেয়াদবি ব্যবহারকারী একটি HTML ফাইল আপলোড করে সেটিকে “ডকুমেন্ট” হিসাবে শেয়ার করে অন্যদের ঠকাতে পারে।
নিয়ন্ত্রণ যোগ করার আগে সিদ্ধান্ত নিন আপনার অ্যাপের জন্য কি বেশি গুরুত্বপূর্ণ: গোপনীয়তা (কে পড়তে পারে), উপলব্ধতা (আপনি সার্ভ রাখতে পারবেন কি), খরচ (স্টোরেজ ও ব্যান্ডউইথ), এবং কমপ্লায়েন্স (ডেটা কোথায় রাখা হচ্ছে ও কতদিন রাখা হবে)। সেই অগ্রাধিকার তালিকা সিদ্ধান্তকে ধারাবাহিক রাখে।
বেশিরভাগ আপলোড ইনসিডেন্ট জটিল হ্যাক নয়—এগুলো সাধারণ “আমি অন্য কারোর ফাইল দেখতে পারি” বাগ। আপলোডকে ফিচারের একটা অংশ হিসেবে দেখুন, পরে লাগানোর মতো কিছু হিসেবে নয়।
একটি নিয়ম দিয়ে শুরু করুন: ডিফল্ট ডিনাই। প্রতিটি আপলোডকৃত অবজেক্টকে ব্যক্তিগত ধরে নিন যতক্ষণ না আপনি স্পষ্টভাবে অ্যাক্সেস অনুমোদন করেন। “ডিফল্টে ব্যক্তিগত” হলো শক্তিশালী বেসলাইন—ইনভয়েস, মেডিকেল ফাইল, অ্যাকাউন্ট ডকুমেন্ট বা কোনোই ব্যবহারকারীর সঙ্গে যুক্ত জিনিসের জন্য। ব্যবহারকারী স্পষ্টভাবে পাবলিক প্রত্যাশা করলে (যেমন পাবলিক অবতার) কেবল তখনই ফাইল পাবলিক করুন, এবং এমন ক্ষেত্ৰে-ও সময়-সীমাবদ্ধ অ্যাক্সেস বিবেচনা করুন।
রোলগুলো সোজা ও আলাদা রাখুন। একটি প্রচলিত বিভাজন:
ফোল্ডার-লেভেল নিয়ম যেমন “/user-uploads/ এর সব কিছু ঠিক আছে” এ ধরনের ওপর নির্ভর করবেন না। প্রতিটি ফাইল পড়ার সময় মালিকানা বা টেন্যান্সি চেক করুন। কেউ দল পরিবর্তন করলে, সংস্থা ছেড়ে গেলে বা ফাইল পুনরায় নিয়োগ হলে এটা আপনাকে রক্ষা করবে।
একটি ভাল সাপোর্ট প্যাটার্ন হলো সংকীর্ণ ও অস্থায়ী: একটি নির্দিষ্ট ফাইলের জন্য অ্যাক্সেস দিন, লগ রাখুন এবং স্বয়ংক্রিয়ভাবে মেয়াদ শেষ করে দিন।
বেশিরভাগ আপলোড আক্রমণ একটি সহজ কৌশল দিয়ে শুরু হয়: একটি ফাইল নাম বা ব্রাউজার হেডার দেখে নিরাপদ মনে হয়, কিন্তু আসলে তা অন্য কিছু। ক্লায়েন্ট যা পাঠায় সবকিছুই অনবিশ্বাসী ধরণে নিন।
একটি allowlist দিয়ে শুরু করুন: আপনি সঠিকভাবে কোন ফরম্যাটগুলো গ্রহণ করবেন তা নির্ধারণ করুন (উদাহরণ: .jpg, .png, .pdf) এবং অন্য সবকিছু প্রত্যাখ্যান করুন। “যে কোনো ইমেজ” বা “যে কোনো ডকুমেন্ট” এড়িয়ে চলুন যদি না সত্যিই দরকার হয়।
ফাইলের এক্সটেনশন বা ক্লায়েন্টের Content-Type হেডারের উপর বিশ্বাস করবেন না। দুটিই সহজেই নকল করা যায়। invoice.pdf নামের ফাইলও executable হতে পারে, এবং Content-Type: image/png মিথ্যা হতে পারে।
একটি শক্তিশালী পদ্ধতি হলো ফাইলের প্রথম বাইটগুলো পরীক্ষা করা, যাকে সাধারণত “magic bytes” বা ফাইল সিগনেচার বলা হয়। অনেক কমন ফরম্যাটের নির্দিষ্ট হেডার থাকে (যেমন PNG ও JPEG)। হেডার অনুমোদিত না হলে প্রত্যাখ্যান করুন।
একটি ব্যবহারিক ভ্যালিডেশন সেটআপ:
নাম পরিবর্তন ভাবনার চেয়েও বেশি গুরুত্বপূর্ণ। যদি আপনি ইউজার-প্রদানকৃত নামগুলো সরাসরি সংরক্ষণ করেন, আপনি পথ-চিট, অদ্ভুত ক্যারেক্টার এবং অনিচ্ছাকৃত ওভাররাইটিং আমন্ত্রণ জানাবেন। সংরক্ষণে একটি জেনারেটেড আইডি ব্যবহার করুন এবং মূল ফাইলনাম শুধুমাত্র প্রদর্শনের জন্য রাখুন।
প্রোফাইল ছবির জন্য শুধুমাত্র JPEG ও PNG গ্রহণ করুন, হেডার যাচাই করুন, এবং সম্ভব হলে মেটাডেটা সরিয়ে দিন। ডকুমেন্টের জন্য PDF-এ সীমাবদ্ধ রাখুন এবং সক্রিয় কন্টেন্ট থাকা কিছু প্রত্যাখ্যান করুন। ভবিষ্যতে যদি SVG বা HTML দরকার হয়, সেগুলোকে সম্ভাব্য এক্সিকিউটেবল ধরে আলাদা আইসোলেশনে রাখুন।
বেশিরভাগ আপলোড আউটেজ জটিল হ্যাক নয়। এগুলো বড় ফাইল, অনেক অনুরোধ, বা ধীর সংযোগের কারণেই সার্ভারগুলো ব্যস্ত হয়ে পড়ে যতক্ষণ না অ্যাপ ধীর বা ডাউন হয়ে যায়। প্রতিটি বাইটকে খরচ মনে করুন।
প্রতিটি ফিচারের জন্য সর্বোচ্চ সাইজ পছন্দ করুন, একটি একগ্লোবাল সংখ্যার পরিবর্তে। একটি অবতার একই লিমিট চাইবে না যেটা একটি কর ডকুমেন্ট বা ছোট ভিডিও দরকার। সবচেয়ে ছোট লিমিট সেট করুন যা এখনও স্বাভাবিক লাগে, তারপর আলাদা “বড় আপলোড” প ath যোগ করুন যখন সত্যিই প্রয়োজন।
ক্লায়েন্ট মিথ্যা বলতে পারে বলে একাধিক স্থানে লিমিট গুরুতর রাখুন: অ্যাপ লজিকে, ওয়েব সার্ভার বা রিভার্স প্রোক্সিতে, আপলোড টাইমআউটে, এবং ঘোষণা করা সাইজ বড় হলে শরীর পড়ার আগে তৎক্ষণাৎ প্রত্যাখ্যান করে দিন।
কংক্রিট উদাহরণ: অবতার 2 MB-এ ক্যাপ, PDF 20 MB-এ ক্যাপ, এবং এর চেয়েও বড় হলে আলাদা ফ্লো লাগবে (যেমন সরাসরি অবজেক্ট স্টোরেজে সাইন করা URL)।
ছোট ফাইলগুলোও লুপে আপলোড হলে DoS হতে পারে। আপলোড এন্ডপয়েন্টে রেট লিমিট যোগ করুন—প্রতি ইউজার ও প্রতি IP হিসেবে। অননুমোদিত ট্রাফিকের জন্য কঠোর লিমিট বিবেচনা করুন।
রিজিউমেবল আপলোড বাস্তব ব্যবহারকারীদের জন্য সহায়ক, কিন্তু সেশন টোকেনটিকে শক্ত রাখতে হবে: সংক্ষিপ্ত মেয়াদ, ব্যবহারকারীর সাথে বাঁধা এবং নির্দিষ্ট ফাইল সাইজ ও গন্তব্যের সাথে বেঁধে দিন। নাহলে “resume” এন্ডপয়েন্ট হয়ে যাবে স্টোরেজে ফ্রি পাইপ।
আপনি যখন কোনো আপলোড ব্লক করেন, ব্যবহারকারীর জন্য পরিষ্কার ত্রুটি দেখান (ফাইল খুব বড়, অনেক অনুরোধ), কিন্তু ভেতরের তথ্য লিক করবেন না (স্ট্যাক ট্রেস, বালতি নাম, ভেন্ডর ডিটেইল)।
নিরাপদ আপলোড শুধুই কি গ্রহণ করছেন তা নয়—এটা ফাইল কোথায় যায় এবং পরে কিভাবে ফিরিয়ে দেওয়া হয় তাতেও গুরুত্বপূর্ণ।
আপলোড বাইটগুলোকে আপনার মেইন ডাটাবেস থেকে দূরে রাখুন। বেশিরভাগ অ্যাপ metadata-ই DB-তে রাখে (owner user ID, original filename, detected type, size, checksum, storage key, created time)। বাইটি-গুলো অবজেক্ট স্টোরেজ বা বড় ব্লবের জন্য ডিজাইন করা ফাইল সার্ভিসে রাখুন।
স্টোরেজ লেভেলে পাবলিক ও প্রাইভেট ফাইল আলাদা রাখুন। বিভিন্ন বালতি বা কন্টেইনার ব্যবহার করুন ভিন্ন নিয়ম নিয়ে। পাবলিক ফাইল (যেমন পাবলিক অবতার) লগইন ছাড়াই পড়া যেতে পারে। প্রাইভেট ফাইল (চুক্তি, ইনভয়েস, মেডিকেল ডকস) কখনই পাবলিক-রিডেবল হওয়া উচিত না, এমনকি কেউ URL অনুমান করলেও।
যতটা সম্ভব আপনার মেইন ডোমেন থেকে ব্যবহারকারীর ফাইল সার্ভ করা এড়িয়ে চলুন। যদি একটি ঝুঁকিপূর্ণ ফাইল স্লিপ করে (HTML, SVG-এ স্ক্রিপ্ট বা ব্রাউজারের MIME স্নিফিং সমস্যা), মেইন ডোমেনে হোস্ট করলে এটি অ্যাকাউন্ট টেকওভার এ পরিণত হতে পারে। একটি ডেডিকেটেড ডাউনলোড ডোমেইন (বা স্টোরেজ ডোমেইন) ব্লাস্ট রেডিয়াস সীমিত করে।
ডাউনলোডে নিরাপদ হেডার বাধ্য করুন। আপনি যা অনুমোদন করেন সেটার উপর ভিত্তি করে Content-Type সেট করুন, ব্যবহারকারীর দাবি নয়। যে কোনো কিছু ব্রাউজার দ্বারা ব্যাখ্যা করা যেতে পারে এমন হলে ডাউনলোড হিসেবে পাঠানোই বাঞ্ছনীয়।
কিছু ডিফল্ট যা বিস্ময় রোধ করে:
Content-Disposition: attachment ব্যবহার করুনContent-Type ব্যবহার করুন (বা application/octet-stream)রিটেনশনও সিকিউরিটি—পরিত্যক্ত আপলোড মুছুন, পুরোনো ভার্সন রিমুভ করুন, অস্থায়ী ফাইলের সময়সীমা সেট করুন। কম ডেটা সংরক্ষণ মানে কম লিক হওয়ার ঝুঁকি।
Signed URLs (প্রেসাইনড URL) খুবই সাধারণ উপায় যাতে ব্যবহারকারীরা স্টোরেজ বালতি পাবলিক না করে এবং প্রতিটি বাইট আপনার API দিয়ে না পাঠিয়ে আপলোড/ডাউনলোড করতে পারে। URL-টি সাময়িক অনুমতি বহন করে, তারপর মেয়াদ শেষ হয়ে যায়।
দুই সাধারণ ফ্লো:
Direct-to-storage API লোড কমায়, কিন্তু স্টোরেজ নীতিমালা ও URL কনে constraints আরও গুরুত্বপূর্ণ করে তোলে।
একটি signed URL-কে ওয়ান-টাইম কী হিসেবে ভাবুন। এটিকে নির্দিষ্ট ও স্বল্প-জীবী রাখুন।
একটি ব্যবহারিক প্যাটার্ন: প্রথমে একটি আপলোড রেকর্ড তৈরি করুন (status: pending), তারপর signed URL ইস্যু করুন। আপলোড হয়ে গেলেই নিশ্চিত করুন অবজেক্টটি আছে এবং প্রত্যাশিত সাইজ ও টাইপ মেলে তারপর status ready করুন।
একটি নিরাপদ আপলোড ফ্লো মূলত স্পষ্ট নিয়ম ও স্পষ্ট স্টেট। প্রতিটি আপলোডকে যাচাই না হওয়া পর্যন্ত অনবিশ্বাসী ধরুন।
লিখে রাখুন প্রতিটি ফিচার কি অনুমোদন করে। প্রোফাইল ছবি ও ট্যাক্স ডকুমেন্ট একই ফাইল টাইপ, সাইজ লিমিট বা ভিজিবিলিটি শেয়ার করা চলবে না।
অনুমোদিত টাইপ ও প্রতিটি ফিচারের জন্য সাইজ লিমিট নির্ধারণ করুন (উদাহরণ: ফটো 5 MB পর্যন্ত; PDF 20 MB পর্যন্ত)। ব্যাকএন্ডে একই নিয়ম জোরদার করুন।
বাইট আসার আগে একটি “upload record” তৈরি করুন। স্টোর করুন: owner (user বা org), purpose (avatar, invoice, attachment), original filename, expected max size, এবং একটি স্ট্যাটাস যেমন pending।
একটি প্রাইভেট লোকেশনে আপলোড করুন। ক্লায়েন্টকে চূড়ান্ত পথ বাছাই করতে দেবেন না।
সার্ভার-সাইডে আবার ভ্যালিডেট করুন: সাইজ, magic bytes/type, allowlist। যদি পাশ করে, তাহলে status পরিবর্তন করে uploaded করুন।
ম্যালওয়্যার স্ক্যান করুন এবং status clean বা quarantined আপডেট করুন। যদি স্ক্যান অ্যাসিঙ্ক্রোনাস হয়, তখন পর্যন্ত অ্যাক্সেস লক করে রাখুন।
শুধু তখনই ডাউনলোড, প্রিভিউ বা প্রসেসিং অনুমতি দিন যখন status clean।
ছোট উদাহরণ: প্রোফাইল ছবির জন্য, ব্যবহারকারীর সাথে টাইটভাবে টাই করা একটি রেকর্ড তৈরি করুন purpose avatar দিয়ে, প্রাইভেটভাবে সংরক্ষণ করুন, নিশ্চিত করুন এটি আসলেই JPEG/PNG (শুধু নাম নয়), স্ক্যান চালান, তারপর প্রিভিউ URL জেনারেট করুন।
ম্যালওয়্যার স্ক্যানিং একটি সেফ্টি নেট—প্রতিশ্রুতি নয়। এটা পরিচিত খারাপ ফাইল ও স্পষ্ট কৌশলগুলো ধরা দেয়, কিন্তু সব কিছু ধরে ফেলবে না। লক্ষ্য হচ্ছে ঝুঁকি কমানো এবং অজানা ফাইলগুলোকে ডিফল্টে ক্ষতিকর না করে রাখা।
একটি নির্ভরযোগ্য প্যাটার্ন হলো আগে কোয়ারেন্টাইন করা। প্রতিটি নতুন আপলোডকে একটি প্রাইভেট, নন-পাবলিক লোকেশনে সংরক্ষণ করুন এবং সেটাকে pending হিসেবে মার্ক করুন। সব চেক পাস করার পরেই তাকে “clean” লোকেশনে সরান বা উপলব্ধ করে দিন।
সিঙ্ক্রোনাস স্ক্যান শুধুমাত্র ছোট ফাইল ও কম ট্র্যাফিকের জন্য কাজ করে কারণ ব্যবহারকারী অপেক্ষা করে। বেশিরভাগ অ্যাপ অ্যাসিঙ্ক্রোনাস স্ক্যান ব্যবহার করে: আপলোড গ্রহণ করুন, “processing” স্টেট ফেরত দিন, ব্যাকগ্রাউন্ডে স্ক্যান করুন।
বেসিক স্ক্যানিং সাধারণত একটি অ্যান্টিভাইরাস ইঞ্জিন (বা সার্ভিস) এবং কিছু গার্ডরেল অন্তর্ভুক্ত করে: AV স্ক্যান, ফাইল-টাইপ চেক (magic bytes), আর্কাইভ সীমা (zip bombs, nested zips, বিশাল আনকমপ্রেসড সাইজ), এবং আপনি না পারলে এমন ফরম্যাট ব্লক করা।
যদি স্ক্যান ব্যর্থ করে, টাইমআউট হয়, বা “অজানা” ফলায়, ফাইলকে সন্দিগ্ধ ধরুন। কোয়ারেন্টাইনে রাখুন এবং ডাউনলোড লিংক দেবেন না। এখানে টিমগুলো জ্বালায়: “scan failed” কখনই “ship it anyway” এ পরিণত হওয়া উচিত নয়।
যখন আপনি কোনো ফাইল ব্লক করেন, বার্তাটি নিরপেক্ষ রাখুন: “আমরা এই ফাইল গ্রহণ করতে পারিনি। ভিন্ন ফাইল চেষ্টা করুন বা সাপোর্টে যোগাযোগ করুন।” নিশ্চিত না হলে ম্যালওয়্যার সনাক্ত করেছি বলবেন না।
ধরা যাক দুইটি ফিচার: একটি প্রোফাইল ফটো (পাবলিকভাবে দেখানো) এবং একটি PDF রিসিট (প্রাইভেট, বিলিং বা সাপোর্টে ব্যবহৃত)। দুটি ক্ষেত্রে আপলোড সমস্যা একই ধরনের, কিন্তু নিয়মগুলো আলাদা হওয়া উচিত।
প্রোফাইল ছবির জন্য কড়া সীমা রাখুন: শুধুমাত্র JPEG/PNG অনুমোদন করুন, সাইজ ক্যাপ করুন (উদাহরণ 2–5 MB), এবং সার্ভার-সাইডে পুনরায় এনকোড করুন যাতে ইউজারের আসল বাইটি সার্ভ না করা হয়। চেক পাস করার পরে তা পাবলিক স্টোরেজে রাখুন।
PDF রিসিটের জন্য বড় সাইজ রাখুন (উদাহরণ 20 MB পর্যন্ত), ডিফল্টে প্রাইভেট রাখুন, এবং প্রধান অ্যাপ ডোমেইন থেকে ইনলাইন রেন্ডার করা এড়িয়ে চলুন।
একটি সহজ স্ট্যাটাস মডেল ব্যবহারকারীদের জানিয়ে রাখে:
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 দিয়ে ফাইল সার্ভ করা যাতে ব্রাউজার ঝুঁকিপূর্ণ কন্টেন্ট ইন্টারপ্রেট করে।মনিটরিং হলো একমাত্র বিষয় টিমগুলো এমনকি পরে বাদ দেয়। আপলোড ভলিউম, গড় সাইজ, শীর্ষ আপলোডার ও এরর রেট ট্র্যাক করুন। একটি বোশ্যুক অ্যাকাউন্ট রাতারাতি হাজার হাজার বড় ফাইল আপলোড করতে পারে।
উদাহরণ: একটি টিম ইউজার-প্রদানকৃত ফাইলনেম ব্যবহার করে avators সংরক্ষণ করে “avatar.png” নামে শেয়ার্ড ফোল্ডারে। একজন ব্যবহারকারী অন্যদের ছবি ওভাররাইট করে দেয়। সমাধান হল: সার্ভার-সাইডে অবজেক্ট কী জেনারেট করা, আপলোড ডিফল্টে প্রাইভেট রাখা, এবং কন্ট্রোলড রেসপন্সের মাধ্যমে রিসাইজড ইমেজ এক্সপোজ করা।
শিপ করার আগে ফাইনাল পাস হিসেবে এটাকে ব্যবহার করুন। প্রতিটি আইটেমকে একটি রিলিজ ব্লকার হিসেবে বিবেচনা করুন, কারণ বেশিরভাগ ইনসিডেন্ট একটি অনুপস্থিত গার্ডরেল থেকে শুরু হয়।
Content-Type, নিরাপদ ফাইলনেম, এবং ডকুমেন্টের জন্য attachment।আপনার নিয়মগুলো সাদামাটা ভাষায় লিখে রাখুন: অনুমোদিত টাইপ, ম্যাক্স সাইজ, কে কি অ্যাক্সেস পায়, signed URL কতক্ষণ বাঁচে, এবং “scan passed” মানে কী। এটা product, engineering, এবং support-শহীদ একটি অংশিক চুক্তি হয়ে যায়।
কিছু টেস্ট যোগ করুন যা সাধারণ ব্যর্থতা ধরবে: অতিরিক্ত বড় ফাইল, নাম পরিবর্তন করে executable, অননুমোদিত রিড, মেয়াদোত্তীর্ণ signed URLs, এবং “scan pending” অবস্থায় ডাউনলোড চেষ্টা। এই টেস্টগুলো একটি ইনসিডেন্টের তুলনায় সস্তা।
আপনি যদি দ্রুত তৈরির উপর থাকেন, এমন ওয়ার্কফ্লো ব্যবহার করুন যেখানে পরিবর্তন প্ল্যান করা এবং নিরাপদে রোলব্যাক করা যায়। Koder.ai (koder.ai) ব্যবহার করা টিমগুলো প্রায়ই planning mode এবং snapshots/rollback-এ নির্ভর করে আপলোড নিয়ম কড়া করার সময়, কিন্তু মূল দরকারি শর্ত থাকে একই: নীতি UI নয়, ব্যাকএন্ড-Enforces করবে।
Start with private by default and treat every upload as untrusted input. Enforce four basics server-side:
If you can answer those clearly, you’re already ahead of most incidents.
Because users can upload a “mystery box” that your app stores and might later serve back to other users. That can lead to:
It’s rarely just “someone uploaded a virus.”
Storing is keeping bytes somewhere. Serving is delivering those bytes to browsers and apps.
The danger is when your app serves user uploads with the same trust and rules as your main site. If a risky file is treated like a normal page, the browser may execute it (or users may trust it too much).
A safer default is: store privately, then serve through controlled download responses with safe headers.
Use default deny and check access every time a file is downloaded or previewed.
Practical rules:
Don’t trust the filename extension or the browser’s Content-Type. Validate on the server:
Because outages often come from boring abuse: too many uploads, huge files, or slow connections tying up server resources.
Defaults that work well:
Treat every byte as cost and every request as potential abuse.
Yes, but do it carefully. Signed URLs let the browser upload/download directly from object storage without making the bucket public.
Good defaults:
Direct-to-storage reduces API load, but it makes scoping and expiration non-negotiable.
The safest pattern is:
pendingScanning helps, but it’s not a guarantee. Use it as a safety net, not your only control.
Practical approach:
The key is policy: “not scanned” should never mean “available.”
Serve files in a way that prevents browsers from interpreting them as web pages.
Good defaults:
Content-Disposition: attachment for documents/uploads/ is fine”Most real bugs are simple “I can see another user’s file” mistakes.
If the bytes don’t match an allowed format, reject the upload.
cleanquarantinedcleanThis prevents “scan failed” or “still processing” files from being shared accidentally.
Content-Type (or application/octet-stream)This reduces the risk that an uploaded file turns into a phishing page or script execution.