FixVibe

// docs / baas security / supabase storage

Sigurnosna checklista za Supabase storage bucket: 22 stavke

Supabase Storage je tanki wrapper oko S3-kompatibilnog bucketa plus isti Row-Level Security model kao baza podataka. To znači da iste RLS zamke koje pogađaju tablice pogađaju i pristup datotekama — uz nekoliko specifičnih za storage koje se pojavljuju kada AI alati za kodiranje žice upload. Ova checklista ima 22 stavke u pet odjeljaka: konfiguracija bucketa, RLS pravila, validacija uploada, signed URL-ovi i operativna higijena. Svaka je provjerljiva u manje od 15 minuta.

Svaka stavka u nastavku je ključna. Za osnovnu mehaniku RLS-a, pogledajte Supabase RLS skener. Za susjednu klasu izlaganja ključeva uz storage, pogledajte Supabase service role ključ izložen u JavaScriptu.

Konfiguracija bucketa

Počnite s ispravnim defaultima. Pogrešno konfiguriran bucket propušta datoteke bez obzira na to je li vaš RLS ispravan ili nije.

  1. Svaki bucket po defaultu postavite na privatan. U Supabase Dashboardu → Storage → Buckets, isključite prekidač Public bucket osim ako imate eksplicitan razlog (marketinški resursi, javni avatari bez PII-ja). Javni bucketi zaobilaze RLS za operacije čitanja — svatko s imenom bucketa može popisivati i preuzimati.
  2. Postavite tvrdo ograničenje veličine datoteke na svaki bucket. Dashboard → Bucket settings → File size limit. 50 MB je razuman default za korisničke uploade; namjerno povećajte za video / velike datoteke. Bez ograničenja, jedan zlonamjeran upload može iscrpiti vašu storage kvotu ili mjesečni bandwidth.
  3. Ograničite dopuštene MIME tipove po bucketu. Popis dopuštenih MIME tipova — eksplicitan popis dopuštenih, ne blokiranih. image/jpeg, image/png, image/webp za bucketove samo za slike. Nikada ne dopuštajte text/html, application/javascript ili image/svg+xml u bucketu za korisnički sadržaj — oni se izvršavaju u pregledniku kada se poslužuju preko signed URL-a.
  4. Koristite jedan bucket po tipu sadržaja, a ne jedan dijeljeni bucket. Postavke po bucketu (veličina, MIME tipovi, RLS pravila) jedina su granularnost koju imate. Bucket user-avatars, bucket document-uploads i bucket public-assets lakše je zaključati nego jedan miješani bucket.
  5. Provjerite CORS konfiguraciju ako frontend uploada. Ako korisnici uploadaju izravno iz preglednika na signed URL, CORS bucketa mora navoditi vaš produkcijski origin. * je prihvatljivo samo za javne buckete — nikada za buckete koji sadrže korisnički PII.

RLS pravila na storage.objects

Supabase Storage pohranjuje metapodatke datoteka u tablici storage.objects. RLS na toj tablici kontrolira tko može čitati, uploadati, ažurirati ili brisati datoteke. Bez RLS-a, javna/privatna oznaka bucketa je vaša jedina zaštita.

  1. Potvrdite da je RLS uključen na storage.objects. SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects'; mora vratiti true. Supabase ga po defaultu uključuje na novim projektima; provjerite da nije onemogućen.
  2. Napišite SELECT pravilo ograničeno preko auth.uid() za privatne buckete. CREATE POLICY "users_read_own_files" ON storage.objects FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);. Konvencija je da datoteke pohranjujete pod [user-id]/[filename] i koristite storage.foldername() da izvučete vlasnika iz putanje.
  3. Napišite INSERT pravilo koje primjenjuje istu konvenciju putanje. CREATE POLICY "users_upload_own" ON storage.objects FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);. Bez WITH CHECK, autenticirani korisnik može uploadati u tuđu mapu.
  4. Dodajte UPDATE i DELETE pravila ako vaša aplikacija podržava uređivanje ili brisanje datoteka. Svaka naredba treba svoje pravilo. Preskakanje DELETE-a znači da autenticirani korisnici ne mogu ukloniti svoje datoteke; preskakanje UPDATE-a znači da prepisivanje datoteke tiho ne uspijeva.
  5. Testirajte pristup između korisnika u dvije sesije preglednika. Prijavite se kao korisnik A, uploadajte datoteku, kopirajte putanju. Prijavite se kao korisnik B u drugom pregledniku, pokušajte dohvatiti datoteku preko REST API-ja. Odgovor mora biti 403 ili 404, nikada 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]);

Validacija uploada

Validirajte svaki upload na serverskoj strani, čak i kada bucket ima ograničenja za MIME i veličinu. AI alati za kodiranje po defaultu generiraju samo klijentsku validaciju; ona ne štiti ništa.

  1. Ponovo provjerite MIME tip na serverskoj strani iz stvarnih bajtova datoteke, a ne iz headera Content-Type. Koristite knjižnicu poput file-type (Node) ili magic-byte sniffing. Napadač može tvrditi Content-Type: image/jpeg na datoteci koja je zapravo poliglotski HTML / JavaScript payload.
  2. Uklonite EXIF metapodatke iz uploadanih slika. EXIF može sadržavati GPS koordinate, serijske brojeve uređaja i timestampe. Koristite sharp s .withMetadata(false) ili exif-parser da to uklonite prije pohrane.
  3. Odbijte SVG-ove koji sadrže script tagove ili onload handlere. SVG je XML — i mnoge AI-generirane aplikacije dopuštaju SVG uploade kao "samo sliku". Koristite DOMPurify na serverskoj strani ili u potpunosti odbijte SVG uploade.
  4. Koristite determinističke, nepogodive nazive datoteka. Ne čuvajte originalni naziv datoteke. Koristite UUID ili hash sadržaja datoteke. Originalni nazivi cure ("passport_scan_2024_01_15.jpg"), a predvidljivi nazivi omogućuju enumeraciju.

Signed URL-ovi

Signed URL-ovi su način na koji klijenti pristupaju privatnim bucketima. Istek, opseg bucketa i ono što se logira su važni.

  1. Postavite default istek signed URL-a na 1 sat ili manje. Metoda createSignedUrl(path, expiresIn) u Supabase JS SDK-u uzima sekunde. Nikada ne koristite vrijednosti poput 31536000 (jedna godina) — URL postaje trajan polujavni link.
  2. Nikada ne pohranjujte signed URL-ove u svojoj bazi. Generirajte svježe na serverskoj strani na svakom zahtjevu. Pohranjen signed URL s istekom od jedne godine koji procuri kroz database dump daje dugotrajan pristup.
  3. Logirajte generiranje signed URL-a, ne samo uploade datoteka. Ako kasnije posumnjate u kompromitaciju, morate znati tko je generirao koji URL i kada. Logirajte auth.uid() + bucket + putanju objekta + timestamp.
  4. Koristite opciju downloadAs kada poslužujete datoteke koje su uploadali korisnici. createSignedUrl(path, expiresIn, { download: '.jpg' }) nameće header Content-Disposition: attachment tako da se datoteka preuzima umjesto renderira — neutralizira klasu izvršavanja HTML / SVG / HTML-u-PDF-u.

Operativna higijena

Konfiguracija storagea s vremenom driftuje. Ove četiri operativne stavke održavaju površinu napada uskom.

  1. Auditirajte buckete kvartalno. Dashboard → Storage → Buckets. Potvrdite da javni/privatni status i popisi MIME tipova odgovaraju onome što aplikacija očekuje. Bucketi stvoreni "privremeno" postaju trajni ako ih nitko ne ukloni.
  2. Pratite anonimne list operacije. Storage logovi (Dashboard → Logs → Storage) bilježe LIST zahtjeve. Skok anonimnih list zahtjeva prema privatnom bucketu znači da ga netko ispituje izvana.
  3. Postavite pravila zadržavanja za efemerne uploade. Privremeni bucketi (pregled slika, draft uploadi) trebaju automatski brisati nakon 24-72 sata preko zakazane funkcije. Neograničeno zadržavanje je odgovornost prema obvezama minimizacije podataka u GDPR-u / CCPA-i.
  4. Pokrećite FixVibe sken mjesečno. Provjera baas.supabase-storage-public ispituje buckete koji odgovaraju na anonimni GET + LIST. Novi bucketi se dodaju; stari mijenjaju vidljivost — samo kontinuirano skeniranje hvata drift.

Sljedeći koraci

Pokrenite FixVibe sken prema svom produkcijskom URL-u — anonimni storage popisi pojavljuju se pod baas.supabase-storage-public. Uparite ovu checklistu s Supabase RLS skenerom za sloj tablica i Supabase service role ključem izloženim u JavaScriptu za susjednost izlaganja ključeva. Za pogrešne konfiguracije storagea kod ostalih BaaS providera, pogledajte Skener BaaS pogrešnih konfiguracija.

// skenirajte svoju baas površinu

Pronađite otvorenu tablicu prije nego što to učini netko drugi.

Ubacite produkcijski URL. FixVibe nabraja BaaS providere s kojima vaša aplikacija razgovara, fingerprintira njihove javne endpointe i prijavljuje što neautenticirani klijent može čitati ili pisati. Besplatno, bez instalacije, bez kartice.

  • Besplatni paket — 3 skena mjesečno, bez kartice pri registraciji.
  • Pasivno BaaS fingerprintiranje — bez potrebe za verifikacijom domene.
  • Supabase, Firebase, Clerk, Auth0, Appwrite i još mnogo toga.
  • AI prompti za popravak na svakom nalazu — zalijepite natrag u Cursor / Claude Code.
Pokrenite besplatni BaaS sken

registracija nije potrebna

Sigurnosna checklista za Supabase storage bucket: 22 stavke — Docs · FixVibe