// docs / baas security / supabase storage
Supabase storage bucket security checklist: 22 items
Supabase Storage S3-compatible bucket વત્તા database જેવા જ Row-Level Security model પર thin wrapper છે. તેનો અર્થ એ છે કે tables ને અસર કરતા RLS pitfalls file access ને અસર કરે છે — અને કેટલીક storage-specific જે AI કોડિંગ ટૂલ uploads ને wire up કરે ત્યારે દેખાય છે. આ checklist પાંચ વિભાગો માં 22 items છે: bucket configuration, RLS policies, upload validation, signed URLs, અને operational hygiene. દરેક 15 મિનિટ કરતા ઓછા સમય માં verifiable છે.
નીચે દરેક item આવશ્યક છે. અંતર્ગત RLS mechanics માટે, Supabase RLS scanner જુઓ. Storage ની નજીકના key-exposure class માટે, Supabase service role key JavaScript માં ઉજાગર જુઓ.
Bucket configuration
યોગ્ય defaults સાથે શરૂ કરો. ખોટી રીતે કોન્ફિગર કરેલ bucket files leak કરે છે, ભલે તમારી RLS સાચી હોય કે ન હોય.
- દરેક bucket ને ડિફોલ્ટ રૂપે private રાખો. Supabase Dashboard → Storage → Buckets માં, જ્યાં સુધી તમારી પાસે explicit કારણ ન હોય (marketing assets, PII વગરના public avatars) ત્યાં સુધી Public bucket toggle ને off પર સેટ કરો. Public buckets read operations માટે RLS ને bypass કરે છે — bucket name ધરાવતો કોઈપણ list અને download કરી શકે છે.
- દરેક bucket પર hard file size limit સેટ કરો. Dashboard → Bucket settings → File size limit. User uploads માટે 50 MB વાજબી default છે; video / large-file use cases માટે ઈરાદાપૂર્વક વધારો. Limit વગર, એક malicious upload તમારી storage quota અથવા તમારી માસિક bandwidth ને ખલાસ કરી શકે છે.
- પ્રતિ bucket allowed MIME types ને restrict કરો. Allowed MIME types list — explicit allowlist, blocklist નહીં. Image-only buckets માટે
image/jpeg,image/png,image/webp. User-content bucket માં ક્યારેયtext/html,application/javascript, અથવાimage/svg+xmlની મંજૂરી ન આપો — તેઓ signed URL દ્વારા served થાય ત્યારે browser માં execute થાય છે. - એક shared bucket ને બદલે પ્રતિ content type એક bucket નો ઉપયોગ કરો. પ્રતિ-bucket settings (size, MIME types, RLS policies) એ તમારી પાસેની granularity છે. એક
user-avatarsbucket, એકdocument-uploadsbucket, અને એકpublic-assetsbucket એક mixed bucket કરતા lock down કરવા સરળ છે. - જો frontend uploads કરે છે તો CORS configuration verify કરો. જો users browser થી signed URL પર સીધા upload કરે છે, તો bucket CORS તમારા production origin ને list કરવો જોઈએ.
*ફક્ત public buckets માટે સ્વીકાર્ય છે — user PII ધરાવતા buckets માટે ક્યારેય નહીં.
storage.objects પર RLS policies
Supabase Storage storage.objects table માં file metadata store કરે છે. એ table પર RLS કોણ files ને read, upload, update, અથવા delete કરી શકે તેને control કરે છે. RLS વગર, bucket નો public/private flag તમારી એકમાત્ર protection છે.
- Confirm કરો કે storage.objects પર RLS enabled છે.
SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects';trueપાછું આપવું જોઈએ. Supabase નવા projects પર તેને ડિફોલ્ટ રૂપે enable કરે છે; verify કરો કે તેને disabled નથી કરાયું. - 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]);. સંમેલન[user-id]/[filename]હેઠળ files store કરવાનું છે અને path માંથી owner કાઢવાstorage.foldername()નો ઉપયોગ કરો. - એ જ path convention enforce કરતી INSERT policy લખો.
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 કરી શકે છે. - જો તમારી app file edits અથવા deletes ને support કરે છે તો UPDATE અને DELETE policies ઉમેરો. દરેક command ને તેની પોતાની policy જરૂરી છે. DELETE છોડી દેવાનો અર્થ છે કે authenticated users તેમની પોતાની files દૂર કરી શકતા નથી; UPDATE છોડી દેવાનો અર્થ છે કે file overwrites ચૂપચાપ fail થાય છે.
- બે browser sessions માં 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નહીં.
-- 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 કોડિંગ ટૂલ ડિફોલ્ટ રૂપે client-only validation generate કરે છે; એ કંઈ protect નથી કરતી.
- MIME type ને server-side ફરી check કરો file ના actual bytes થી,
Content-Typeheader થી નહીં.file-type(Node) જેવી library અથવા magic-byte sniffing નો ઉપયોગ કરો. એક હુમલાખોર એવી file પરContent-Type: image/jpegનો દાવો કરી શકે જે ખરેખર polyglot HTML / JavaScript payload હોય. - Uploaded images માંથી EXIF metadata strip કરો. EXIF માં GPS coordinates, device serial numbers, અને timestamps હોઈ શકે છે. Storage પહેલા strip કરવા
.withMetadata(false)સાથેsharpઅથવાexif-parserનો ઉપયોગ કરો. - એવી SVGs reject કરો જેમાં
scripttags અથવાonloadhandlers હોય. SVG XML છે — અને ઘણી AI-generated apps SVG uploads ને "ફક્ત એક image" તરીકે મંજૂરી આપે છે. Server-sideDOMPurifyનો ઉપયોગ કરો અથવા SVG uploads ને સંપૂર્ણપણે refuse કરો. - Deterministic, unguessable filenames નો ઉપયોગ કરો. મૂળ filename ને preserve ન કરો. UUID અથવા file contents નો hash નો ઉપયોગ કરો. મૂળ filenames leak કરે છે ("
passport_scan_2024_01_15.jpg") અને predictable names enumeration ને સક્ષમ કરે છે.
Signed URLs
Signed URLs એ રીત છે જે clients private buckets ને access કરે છે. Expiry, bucket scope, અને શું log થાય છે તે મહત્વનું છે.
- Signed-URL expiry ને ડિફોલ્ટ રૂપે 1 કલાક અથવા તેનાથી ઓછું રાખો. Supabase JS SDK નો
createSignedUrl(path, expiresIn)seconds લે છે.31536000(એક વર્ષ) જેવા values ક્યારેય ઉપયોગ ન કરો — URL એક permanent semi-public link બની જાય છે. - તમારા database માં ક્યારેય signed URLs store ન કરો. દરેક request પર server-side ઉપર નવા generate કરો. 1-વર્ષ ની expiry સાથેનું stored signed URL જે database dump મારફતે leak થાય તે long-term access આપે છે.
- ફક્ત file uploads નહીં, signed-URL generation ને log કરો. જો તમે પાછળથી compromise ની શંકા કરો, તો તમારે જાણવાની જરૂર છે કે કોણે કયું URL ક્યારે generate કર્યું.
auth.uid()+ bucket + object path + timestamp log કરો. - User-uploaded files serve કરતી વખતે
downloadAsoption નો ઉપયોગ કરો.createSignedUrl(path, expiresIn, { download: '.jpg' })Content-Disposition: attachmentheader force કરે છે જેથી file render થવાને બદલે download થાય — HTML / SVG / HTML-in-PDF execution class ને હરાવે છે.
Operational hygiene
Storage configuration સમય સાથે drift થાય છે. આ ચાર operational items સપાટી ને tight રાખે છે.
- Buckets નું ત્રિમાસિક audit કરો. Dashboard → Storage → Buckets. App જે અપેક્ષા રાખે છે તેની સાથે public/private state અને MIME-type lists મેળ ખાય છે કે કેમ તે confirm કરો. "કામચલાઉ" બનાવેલા buckets કાયમી બની જાય છે જો કોઈ તેમને દૂર ન કરે.
- Anonymous list operations monitor કરો. Storage logs (Dashboard → Logs → Storage)
LISTrequests record કરે છે. Private bucket સામે anonymous list requests નો વધારો સંકેત છે કે કોઈ બહારથી તેને probe કરી રહ્યું છે. - Ephemeral uploads માટે retention policy સેટ કરો. Temp buckets (image preview, draft uploads) એ scheduled function મારફતે 24-72 કલાક પછી auto-delete થવા જોઈએ. અનિશ્ચિત retention એ GDPR / CCPA data-minimisation જવાબદારીઓ હેઠળ liability છે.
- માસિક FixVibe scan ચલાવો.
baas.supabase-storage-publiccheck એવા buckets માટે probe કરે છે જે anonymousGET+LISTને response આપે છે. નવા buckets ઉમેરાય છે; જૂના visibility બદલે છે — ફક્ત સતત scanning drift પકડે છે.
આગળના પગલાં
તમારા production URL સામે FixVibe scan ચલાવો — anonymous storage listings baas.supabase-storage-public હેઠળ દેખાય છે. Table layer માટે આ checklist ને Supabase RLS scanner સાથે અને key-exposure adjacency માટે Supabase service role key JavaScript માં ઉજાગર સાથે pair કરો. અન્ય BaaS providers માં storage misconfigurations માટે, BaaS misconfiguration scanner જુઓ.
