// docs / baas security / supabase storage
Supabase storage bucket biztonsági checklist: 22 pont
A Supabase Storage egy vékony burkoló egy S3-kompatibilis bucket körül, plusz ugyanaz a row-level security modell, mint az adatbázis. Ez azt jelenti, hogy ugyanazok az RLS-buktatók, amelyek a táblákat érintik, érintik a fájlhozzáférést is — plusz néhány storage-specifikus, ami akkor jelenik meg, amikor az MI-kódoló eszközök feltöltést drótoznak. Ez a checklist 22 pont öt szakaszon át: bucket-konfiguráció, RLS-policy-k, feltöltés-érvényesítés, signed URL-ek és üzemeltetési higiénia. Mindegyik 15 percen belül ellenőrizhető.
Az alábbi minden pont elengedhetetlen. Az alapvető RLS-mechanikáért lásd a Supabase RLS-szkenner cikket. A storage-szal szomszédos kulcs-kitettségi osztályért lásd A Supabase service role kulcs JavaScriptben felfedve cikket.
Bucket-konfiguráció
Kezdj a helyes alapértelmezésekkel. Egy hibásan konfigurált bucket fájlokat szivárogtat, függetlenül attól, hogy az RLS-ed helyes-e.
- Alapértelmezésben minden bucket legyen privát. A Supabase Dashboardon → Storage → Buckets, állítsd a Public bucket kapcsolót kikapcsolt állásba, hacsak nincs explicit okod (marketingeszközök, nyilvános avatárok PII nélkül). A nyilvános bucketök megkerülik az RLS-t olvasási műveletekre — bárki a bucket nevével tud listázni és letölteni.
- Állíts kemény fájlméret-korlátot minden bucketre. Dashboard → Bucket-beállítások → Fájlméret-korlát. 50 MB értelmes alapértelmezés felhasználói feltöltésekhez; emeld tudatosan videó- / nagy-fájl-használati esetekhez. Korlát nélkül egyetlen rosszindulatú feltöltés kimerítheti a storage-kvótádat vagy a havi sávszélességedet.
- Korlátozd az engedélyezett MIME-típusokat bucketenként. Engedélyezett MIME-típusok listája — explicit allowlist, nem blocklist.
image/jpeg,image/png,image/webpkép-only bucketekhez. Soha ne engedjtext/html-t,application/javascript-et vagyimage/svg+xml-et egy felhasználói tartalom bucketben — futnak a böngészőben, amikor signed URL-en keresztül szolgálják ki őket. - Használj egy bucketet tartalomtípusonként, ne egy közös bucketet. A bucketenkénti beállítások (méret, MIME-típusok, RLS-policy-k) jelentik a granularitást, amellyel rendelkezel. Egy
user-avatarsbucket, egydocument-uploadsbucket és egypublic-assetsbucket könnyebben zárható le, mint egy vegyes bucket. - Ellenőrizd a CORS-konfigurációt, ha a frontend tölt fel. Ha a felhasználók közvetlenül a böngészőből töltenek fel egy signed URL-re, a bucket CORS-jának listáznia kell az éles origin-edet. A
*csak nyilvános bucketökhöz elfogadható — soha nem felhasználói PII-t tartalmazó bucketökhöz.
RLS-policy-k a storage.objects-en
A Supabase Storage a fájl-metaadatokat a storage.objects táblában tárolja. Az ezen táblán lévő RLS szabályozza, ki olvashat, tölthet fel, frissíthet vagy törölhet fájlokat. RLS nélkül a bucket public/private flagje az egyetlen védelmed.
- Erősítsd meg, hogy az RLS engedélyezett a storage.objects-en. A
SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects';true-t kell visszaadjon. A Supabase új projekteken alapból engedélyezi; ellenőrizd, hogy nem lett-e letiltva. - Írj egy SELECT policy-t, ami
auth.uid()-re szűkít privát bucketökhöz.CREATE POLICY "users_read_own_files" ON storage.objects FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);. A konvenció az, hogy a fájlokat[user-id]/[filename]alatt tárolod, és astorage.foldername()-mel nyered ki a tulajdonost az útvonalból. - Írj egy INSERT policy-t, ami ugyanazt az útvonal-konvenciót érvényesíti.
CREATE POLICY "users_upload_own" ON storage.objects FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);. WITH CHECK nélkül egy hitelesített felhasználó tud feltölteni egy másik felhasználó mappájába. - Adj hozzá UPDATE és DELETE policy-ket, ha az alkalmazásod támogatja a fájlszerkesztést vagy -törlést. Minden parancsnak szüksége van saját policy-re. A DELETE kihagyása azt jelenti, hogy a hitelesített felhasználók nem tudják saját fájljaikat eltávolítani; az UPDATE kihagyása azt jelenti, hogy a fájl-felülírások csendben elbuknak.
- Tesztelj felhasználók közti hozzáférést két böngészőmenetben. Jelentkezz be A felhasználóként, tölts fel egy fájlt, másold ki az útvonalat. Jelentkezz be B felhasználóként egy másik böngészőben, próbáld lekérni a fájlt a REST API-n keresztül. A válasznak
403-nak vagy404-nek kell lennie, soha nem200-nak.
-- 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]);Feltöltés-érvényesítés
Érvényesíts minden feltöltést szerveroldalon, még akkor is, ha a bucketnek vannak MIME- és méretkorlátai. Az MI-kódoló eszközök alapból csak kliensoldali érvényesítést generálnak; az semmit nem véd.
- Ellenőrizd újra a MIME-típust szerveroldalon a fájl tényleges byte-jaiból, ne a
Content-Typefejlécből. Használj olyan könyvtárat, mint afile-type(Node) vagy magic-byte szniffolást. Egy támadó állíthatja aContent-Type: image/jpeg-et egy fájlra, ami valójában egy poliglott HTML / JavaScript payload. - Távolítsd el az EXIF-metaadatokat a feltöltött képekből. Az EXIF GPS-koordinátákat, eszköz-sorozatszámokat és időbélyegeket tartalmazhat. Használd a
sharp-ot.withMetadata(false)-szal vagy azexif-parser-t a tárolás előtti eltávolításhoz. - Utasítsd el azokat az SVG-ket, amik
scripttageket vagyonloadhandlereket tartalmaznak. Az SVG XML — és sok MI-generált alkalmazás engedélyezi az SVG-feltöltéseket „csak egy képként". HasználjDOMPurify-t szerveroldalon, vagy utasítsd el teljesen az SVG-feltöltéseket. - Használj determinisztikus, kitalálhatatlan fájlneveket. Ne őrizd meg az eredeti fájlnevet. Használj UUID-t vagy a fájltartalom hashét. Az eredeti fájlnevek szivárognak ("
passport_scan_2024_01_15.jpg"), és a kiszámítható nevek lehetővé teszik az enumerációt.
Signed URL-ek
A signed URL-ek azok, ahogyan a kliensek hozzáférnek a privát bucketökhöz. A lejárat, a bucket-scope és hogy mit naplózunk, fontos.
- Állítsd a signed URL alapértelmezett lejáratát 1 órára vagy kevesebbre. A Supabase JS SDK
createSignedUrl(path, expiresIn)függvénye másodperceket vesz. Soha ne használj olyan értékeket, mint31536000(egy év) — az URL állandó félig-nyilvános linkké válik. - Soha ne tárolj signed URL-eket az adatbázisodban. Generálj frisseket szerveroldalon minden kérésnél. Egy 1-éves lejáratú tárolt signed URL, ami egy DB-dumpon keresztül szivárog, hosszú távú hozzáférést biztosít.
- Naplózd a signed URL generálását, ne csak a fájl-feltöltéseket. Ha később kompromittálódásra gyanakszol, tudnod kell, ki generált melyik URL-t mikor. Naplózz
auth.uid()+ bucket + objektum-útvonal + időbélyeget. - Használd a
downloadAsopciót, amikor felhasználó által feltöltött fájlokat szolgálsz ki. AcreateSignedUrl(path, expiresIn, { download: '.jpg' })kényszerít egyContent-Disposition: attachmentfejlécet, így a fájl letöltődik, ahelyett, hogy renderelődne — kiveszi a HTML / SVG / HTML-in-PDF futtatási osztályt.
Üzemeltetési higiénia
A storage-konfiguráció idővel sodródik. Ez a négy üzemeltetési pont szorosan tartja a felületet.
- Auditáld a bucketöket negyedévente. Dashboard → Storage → Buckets. Erősítsd meg, hogy a public/private állapot és a MIME-típus-listák megfelelnek annak, amit az alkalmazás vár. A „ideiglenesen" létrehozott bucketök állandóvá válnak, ha senki nem távolítja el őket.
- Figyeld az anonim list műveleteket. A Storage-logok (Dashboard → Logs → Storage) rögzítik a
LISTkéréseket. Egy spike az anonim list kérésekben egy privát bucket ellen azt jelenti, hogy valaki kívülről szondázza. - Állíts megőrzési házirendet az efemer feltöltésekhez. A temp bucketök (képelőnézet, vázlat-feltöltések) 24-72 óra után automatikusan törlődjenek egy ütemezett függvény segítségével. A határozatlan megőrzés felelősség a GDPR / CCPA adatminimalizálási kötelezettségek alatt.
- Futtass havonta FixVibe-szkennelést. A
baas.supabase-storage-publicellenőrzés azokat a bucketöket szondázza, amelyek anonimGET+LIST-re válaszolnak. Új bucketök adódnak hozzá; a régiek láthatósága változik — csak a folyamatos szkennelés fogja el a sodródást.
Következő lépések
Futtass egy FixVibe-szkennelést az éles URL-edre — az anonim storage-listázások a baas.supabase-storage-public alatt jelennek meg. Párosítsd ezt a checklistet a Supabase RLS-szkennerrel a táblaréteghez és a Supabase service role kulcs JavaScriptben felfedve cikkel a szomszédos kulcs-kitettséghez. Más BaaS-szolgáltatókon átívelő storage-hibás konfigurációkért lásd a BaaS hibás konfiguráció szkenner cikket.
