FixVibe

// docs / baas security / supabase storage

Supabase storage bucket security checklist: 22 আইটেম

Supabase Storage একটি S3-সামঞ্জস্যপূর্ণ bucket-এর চারপাশে একটি পাতলা wrapper এবং database-এর মতোই একই Row-Level Security model। অর্থাৎ যে একই RLS pitfalls tables-কে প্রভাবিত করে সেগুলি file access-কেও প্রভাবিত করে — এবং কিছু storage-specific যা AI কোডিং টুলগুলি uploads wire করার সময় উদিত হয়। এই checklist পাঁচটি section-এ 22 আইটেম: bucket configuration, RLS policies, upload validation, signed URLs, এবং operational hygiene। প্রতিটি 15 মিনিটের কম সময়ে verifiable।

নিচের প্রতিটি আইটেম অপরিহার্য। অন্তর্নিহিত RLS mechanics-এর জন্য, Supabase RLS scanner দেখুন। Storage-এর সংলগ্ন key-exposure class-এর জন্য, JavaScript-এ Supabase service role key উন্মোচিত দেখুন।

Bucket configuration

সঠিক defaults দিয়ে শুরু করুন। একটি misconfigured bucket files leak করে, আপনার RLS সঠিক হোক বা না হোক।

  1. প্রতিটি bucket default-এ private রাখুন। Supabase Dashboard → Storage → Buckets-এ, Public bucket toggle off-এ set করুন যতক্ষণ আপনার একটি স্পষ্ট কারণ না থাকে (marketing assets, PII ছাড়া public avatars)। Public buckets read operations-এর জন্য RLS bypass করে — bucket নাম সহ যে কেউ list এবং download করতে পারে।
  2. প্রতিটি bucket-এ একটি hard file size limit set করুন। Dashboard → Bucket settings → File size limit। User uploads-এর জন্য 50 MB একটি সংবেদনশীল default; video / large-file use cases-এর জন্য এটি ইচ্ছাকৃতভাবে বাড়ান। সীমা ছাড়া, একটি একক ক্ষতিকারক upload আপনার storage quota বা আপনার monthly bandwidth শেষ করতে পারে।
  3. প্রতি bucket allowed MIME types সীমাবদ্ধ করুন। Allowed MIME types list — স্পষ্ট allowlist, blocklist নয়। শুধুমাত্র-image bucket-এর জন্য image/jpeg, image/png, image/webp। User-content bucket-এ কখনো text/html, application/javascript, বা image/svg+xml অনুমতি দেবেন না — signed URL-এর মাধ্যমে serve হলে সেগুলি browser-এ execute হয়।
  4. একটি shared bucket নয়, প্রতি content type-এ একটি bucket ব্যবহার করুন। Per-bucket settings (size, MIME types, RLS policies) সেই granularity যা আপনার কাছে আছে। একটি user-avatars bucket, একটি document-uploads bucket, এবং একটি public-assets bucket একটি mixed bucket-এর চেয়ে lock down করা সহজ।
  5. Frontend uploads হলে CORS configuration যাচাই করুন। যদি users browser থেকে সরাসরি signed URL-এ upload করে, bucket CORS-এ অবশ্যই আপনার production origin তালিকাভুক্ত থাকতে হবে। * শুধুমাত্র public buckets-এর জন্য গ্রহণযোগ্য — user PII সহ buckets-এর জন্য কখনোই নয়।

storage.objects-এ RLS policies

Supabase Storage storage.objects table-এ file metadata সংরক্ষণ করে। সেই table-এ RLS নিয়ন্ত্রণ করে কে files পড়তে, upload করতে, update করতে, বা delete করতে পারে। RLS ছাড়া, bucket-এর public/private flag আপনার একমাত্র সুরক্ষা।

  1. Confirm করুন যে storage.objects-এ RLS enabled। SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects'; অবশ্যই true return করতে হবে। Supabase নতুন projects-এ এটি default-এ enable করে; verify করুন যে এটি disabled হয়নি।
  2. private buckets-এর জন্য auth.uid()-এ scoped একটি SELECT policy লিখুন। CREATE POLICY "users_read_own_files" ON storage.objects FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);। প্রচলিত নিয়ম হল files-কে [user-id]/[filename]-এর অধীনে সংরক্ষণ করা এবং path থেকে owner বের করতে storage.foldername() ব্যবহার করা।
  3. একটি INSERT policy লিখুন যা একই path convention প্রয়োগ করে। CREATE POLICY "users_upload_own" ON storage.objects FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);। WITH CHECK ছাড়া, একজন authenticated user অন্য user-এর folder-এ upload করতে পারে।
  4. আপনার অ্যাপ file edits বা deletes support করলে UPDATE এবং DELETE policies যোগ করুন। প্রতিটি command-এর নিজস্ব policy প্রয়োজন। DELETE skip করার অর্থ authenticated users তাদের নিজস্ব files সরাতে পারে না; UPDATE skip করার অর্থ file overwrites নীরবে fail হয়।
  5. দুটি browser session-এ cross-user access test করুন। User A হিসাবে sign in করুন, একটি file upload করুন, path copy করুন। অন্য browser-এ User B হিসাবে sign in করুন, REST API-এর মাধ্যমে file fetch করার চেষ্টা করুন। Response অবশ্যই 403 বা 404 হতে হবে, কখনো 200 নয়।
sql
-- Confirm RLS on storage.objects
SELECT rowsecurity
FROM   pg_tables
WHERE  schemaname = 'storage' AND tablename = 'objects';

-- SELECT policy: scope reads to the owning user's folder.
CREATE POLICY "users_read_own_files"
  ON storage.objects
  FOR SELECT
  USING (auth.uid()::text = (storage.foldername(name))[1]);

-- INSERT policy: enforce the [user-id]/[filename] path convention.
CREATE POLICY "users_upload_own"
  ON storage.objects
  FOR INSERT
  WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);

Upload validation

প্রতিটি upload server-side validate করুন, এমনকি যখন bucket-এ MIME এবং size constraints থাকে। AI কোডিং টুলগুলি default-এ client-only validation তৈরি করে; এটি কিছুই রক্ষা করে না।

  1. File-এর প্রকৃত bytes থেকে server-side MIME type পুনরায় check করুন, Content-Type header থেকে নয়। file-type (Node) বা magic-byte sniffing-এর মতো একটি library ব্যবহার করুন। একজন আক্রমণকারী এমন একটি file-এ Content-Type: image/jpeg দাবি করতে পারে যা আসলে একটি polyglot HTML / JavaScript payload।
  2. Uploaded images থেকে EXIF metadata strip করুন। EXIF-এ GPS coordinates, device serial numbers, এবং timestamps থাকতে পারে। Storage-এর আগে strip করতে .withMetadata(false) সহ sharp বা exif-parser ব্যবহার করুন।
  3. যে SVGs-তে script tags বা onload handlers আছে সেগুলি reject করুন। SVG হল XML — এবং অনেক AI-generated অ্যাপ SVG uploads-কে "শুধু একটি image" হিসাবে অনুমতি দেয়। Server-side DOMPurify ব্যবহার করুন বা সম্পূর্ণভাবে SVG uploads প্রত্যাখ্যান করুন।
  4. Deterministic, unguessable filenames ব্যবহার করুন। মূল filename সংরক্ষণ করবেন না। একটি UUID বা file contents-এর একটি hash ব্যবহার করুন। মূল filenames leak করে ("passport_scan_2024_01_15.jpg") এবং predictable names enumeration সক্ষম করে।

Signed URLs

Signed URLs হল clients কীভাবে private buckets অ্যাক্সেস করে। Expiry, bucket scope, এবং কী log হয় তা গুরুত্বপূর্ণ।

  1. Signed-URL expiry default 1 ঘণ্টা বা কম রাখুন। Supabase JS SDK-এর createSignedUrl(path, expiresIn) seconds নেয়। 31536000 (এক বছর)-এর মতো মান কখনো ব্যবহার করবেন না — URL একটি স্থায়ী semi-public link হয়ে যায়।
  2. Signed URLs কখনো আপনার database-এ সংরক্ষণ করবেন না। প্রতিটি request-এ server-side fresh ones তৈরি করুন। একটি 1-বছরের expiry সহ একটি stored signed URL যা database dump-এর মাধ্যমে leak হয় সেটি দীর্ঘমেয়াদী access দেয়।
  3. শুধু file uploads নয়, signed-URL generation log করুন। পরে compromise সন্দেহ করলে, আপনাকে জানতে হবে কে কখন কোন URL তৈরি করেছিল। auth.uid() + bucket + object path + timestamp log করুন।
  4. User-uploaded files serve করার সময় downloadAs option ব্যবহার করুন। createSignedUrl(path, expiresIn, { download: '.jpg' }) একটি Content-Disposition: attachment header force করে যাতে file render-এর পরিবর্তে download হয় — HTML / SVG / HTML-in-PDF execution class পরাজিত করে।

Operational hygiene

Storage configuration সময়ের সাথে সাথে drift করে। এই চারটি operational আইটেম পৃষ্ঠকে টাইট রাখে।

  1. ত্রৈমাসিকভাবে buckets audit করুন। Dashboard → Storage → Buckets। Confirm করুন public/private state এবং MIME-type lists অ্যাপ যা আশা করে তার সাথে মেলে। "অস্থায়ীভাবে" তৈরি buckets স্থায়ী হয়ে যায় যদি কেউ সেগুলি না সরায়।
  2. Anonymous list operations monitor করুন। Storage logs (Dashboard → Logs → Storage) LIST requests record করে। একটি private bucket-এর বিরুদ্ধে anonymous list requests-এর একটি spike মানে কেউ বাইরে থেকে এটি probe করছে।
  3. Ephemeral uploads-এর জন্য একটি retention policy set করুন। Temp buckets (image preview, draft uploads) একটি scheduled function-এর মাধ্যমে 24-72 ঘণ্টা পরে auto-delete হওয়া উচিত। অনির্দিষ্ট retention GDPR / CCPA data-minimisation obligations-এর অধীনে একটি দায়।
  4. মাসিক একটি FixVibe scan চালান। baas.supabase-storage-public check যে buckets anonymous GET + LIST-এর প্রতিক্রিয়া জানায় সেগুলির জন্য probe করে। নতুন buckets যোগ হয়; পুরানো buckets visibility পরিবর্তন করে — শুধুমাত্র continuous scanning drift ধরে।

পরবর্তী পদক্ষেপ

আপনার production URL-এর বিরুদ্ধে একটি FixVibe scan চালান — anonymous storage listings baas.supabase-storage-public-এর অধীনে দেখায়। Table layer-এর জন্য এই checklist Supabase RLS scanner-এর সাথে এবং key-exposure সংলগ্নের জন্য JavaScript-এ Supabase service role key উন্মোচিত-এর সাথে যুক্ত করুন। অন্যান্য BaaS providers-এ storage misconfigurations-এর জন্য, BaaS misconfiguration scanner দেখুন।

// আপনার baas পৃষ্ঠ scan করুন

অন্য কেউ আগে খুঁজে পাওয়ার আগে খোলা table খুঁজে বের করুন।

একটি প্রোডাকশন URL দিন। FixVibe আপনার অ্যাপ যে BaaS providers-এর সাথে কথা বলে সেগুলি গণনা করে, তাদের public endpoints-এর fingerprint নেয়, এবং রিপোর্ট করে যে একটি unauthenticated client কী পড়তে বা লিখতে পারে। ফ্রি, কোনো install নেই, কোনো কার্ড নেই।

  • ফ্রি tier — 3 scans / মাস, signup-এর জন্য কার্ড নেই।
  • Passive BaaS fingerprinting — domain verification প্রয়োজন নেই।
  • Supabase, Firebase, Clerk, Auth0, Appwrite, এবং আরও অনেক।
  • প্রতিটি finding-এ AI fix prompts — Cursor / Claude Code-এ paste করুন।
একটি ফ্রি BaaS scan চালান

signup প্রয়োজন নেই

Supabase storage bucket security checklist: 22 আইটেম — Docs · FixVibe