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 tabele pogađaju i pristup fajlovima — 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 politike, 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 konfigurisan bucket curi fajlove bez obzira na to da li je 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 — svako s imenom bucketa može da lista i preuzima.
  2. Postavite tvrdo ograničenje veličine fajla na svaki bucket. Dashboard → Bucket settings → File size limit. 50 MB je razuman default za korisničke uploade; namjerno povećajte za video / velike fajlove. Bez ograničenja, jedan zlonamjeran upload može iscrpiti vašu storage kvotu ili mjesečni bandwidth.
  3. Ograničite dozvoljene MIME tipove po bucketu. Lista dozvoljenih MIME tipova — eksplicitna lista dozvoljenih, ne blokiranih. image/jpeg, image/png, image/webp za bucketove samo za slike. Nikada ne dozvoljavajte 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, ne jedan dijeljeni bucket. Postavke po bucketu (veličina, MIME tipovi, RLS politike) 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 uploaduje. Ako korisnici uploaduju direktno 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 politike na storage.objects

Supabase Storage čuva metapodatke fajlova u tabeli storage.objects. RLS na toj tabeli kontroliše ko može čitati, uploadovati, ažurirati ili brisati fajlove. 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 politiku ograničenu 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 fajlove čuvate pod [user-id]/[filename] i koristite storage.foldername() da izvučete vlasnika iz putanje.
  3. Napišite INSERT politiku koja 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 uploadovati u tuđi folder.
  4. Dodajte UPDATE i DELETE politike ako vaša aplikacija podržava uređivanje ili brisanje fajlova. Svaka komanda treba svoju politiku. Preskakanje DELETE-a znači da autenticirani korisnici ne mogu ukloniti svoje fajlove; preskakanje UPDATE-a znači da prepisivanje fajla tiho ne uspijeva.
  5. Testirajte pristup između korisnika u dvije browser sesije. Prijavite se kao korisnik A, uploadujte fajl, kopirajte putanju. Prijavite se kao korisnik B u drugom pregledniku, pokušajte dohvatiti fajl 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 fajla, a ne iz headera Content-Type. Koristite biblioteku poput file-type (Node) ili magic-byte sniffing. Napadač može tvrditi Content-Type: image/jpeg na fajlu koji je zapravo poliglotski HTML / JavaScript payload.
  2. Uklonite EXIF metapodatke iz uploadovanih slika. EXIF može sadržavati GPS koordinate, serijske brojeve uređaja i timestampove. Koristite sharp s .withMetadata(false) ili exif-parser da to uklonite prije čuvanja.
  3. Odbacite SVG-ove koji sadrže script tagove ili onload handlere. SVG je XML — i mnoge AI-generirane aplikacije dozvoljavaju SVG uploade kao "samo sliku". Koristite DOMPurify na serverskoj strani ili u potpunosti odbijte SVG uploade.
  4. Koristite determinističke, nepogodive nazive fajlova. Ne čuvajte originalni naziv fajla. Koristite UUID ili hash sadržaja fajla. Originalni nazivi curi ("passport_scan_2024_01_15.jpg"), a predvidljivi nazivi omogućavaju enumeraciju.

Signed URL-ovi

Signed URL-ovi su način na koji klijenti pristupaju privatnim bucketima. Istek, opseg bucketa i ono što se loguje 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 permanentni polujavni link.
  2. Nikada ne čuvajte signed URL-ove u svojoj bazi. Generirajte svježe na serverskoj strani na svakom zahtjevu. Sačuvani signed URL s istekom od jedne godine koji procuri kroz database dump daje dugotrajan pristup.
  3. Logirajte generisanje signed URL-a, ne samo uploade fajlova. Ako kasnije posumnjate na kompromitaciju, morate znati ko je generisao koji URL i kada. Logirajte auth.uid() + bucket + putanja objekta + timestamp.
  4. Koristite opciju downloadAs kada poslužujete fajlove koje su uploadovali korisnici. createSignedUrl(path, expiresIn, { download: '.jpg' }) nameće header Content-Disposition: attachment tako da se fajl preuzima umjesto renderuje — 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. Auditujte buckete kvartalno. Dashboard → Storage → Buckets. Potvrdite da javni/privatni status i liste MIME tipova odgovaraju onome što aplikacija očekuje. Bucketi kreirani "privremeno" postaju trajni ako ih niko 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 neko ispituje izvana.
  3. Postavite politiku 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 obavezama 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 — anonimne storage liste pojavljuju se pod baas.supabase-storage-public. Uparite ovu checklistu s Supabase RLS skenerom za sloj tabela 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 tabelu prije nego što to neko drugi učini.

Ubacite produkcijski URL. FixVibe nabraja BaaS providere s kojima vaša aplikacija razgovara, fingerprintira njihove javne endpointe i prijavljuje šta 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 nazad u Cursor / Claude Code.
Pokrenite besplatni BaaS sken

registracija nije potrebna

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