// docs / baas security / supabase storage
Kontrolní seznam zabezpečení úložného koše Supabase: 22 položek
Supabase Storage je tenký obal kolem S3-kompatibilního koše plus stejný model zabezpečení na úrovni řádků jako databáze. To znamená, že stejné nástrahy RLS, které ovlivňují tabulky, ovlivňují přístup k souborům — a několik specifických pro úložiště, které se objevují, když AI nástroje pro kódování zapojují nahrávání. Tento kontrolní seznam má 22 položek napříč pěti sekcemi: konfigurace koše, politiky RLS, validace nahrávání, podepsané URL a operační hygiena. Každá je ověřitelná za méně než 15 minut.
Každá níže uvedená položka je zásadní. Pro mechaniku RLS, která stojí za tím, viz Skener Supabase RLS. Pro třídu vystavení klíče sousedící s úložištěm viz Servisní klíč Supabase vystavený v JavaScriptu.
Konfigurace koše
Začněte se správnými výchozími hodnotami. Špatně nakonfigurovaný koš uniká soubory, ať už je vaše RLS správné nebo ne.
- Výchozí stav každého koše nastavte na privátní. V Supabase Dashboard → Storage → Buckets nastavte přepínač Public bucket na vypnuto, pokud nemáte explicitní důvod (marketingové podklady, veřejné avatary bez PII). Veřejné koše obcházejí RLS pro operace čtení — kdokoliv se jménem koše může vypisovat a stahovat.
- Nastavte tvrdý limit velikosti souboru na každém koši. Dashboard → Bucket settings → File size limit. 50 MB je rozumný výchozí stav pro uživatelské nahrávání; záměrně zvyšte pro video / velké soubory. Bez limitu může jediné škodlivé nahrání vyčerpat vaši kvótu úložiště nebo měsíční šířku pásma.
- Omezte povolené MIME typy na koš. Seznam povolených MIME typů — explicitní allowlist, ne blocklist.
image/jpeg,image/png,image/webppro koše pouze pro obrázky. V uživatelském obsahovém koši nikdy nepovolujtetext/html,application/javascriptneboimage/svg+xml— spouštějí se v prohlížeči, když jsou obsluhovány přes podepsanou URL. - Použijte jeden koš na typ obsahu, ne jeden sdílený koš. Nastavení per koš (velikost, MIME typy, politiky RLS) je granularita, kterou máte. Koš
user-avatars, košdocument-uploadsa košpublic-assetsse uzamykají snadněji než jeden smíšený koš. - Ověřte konfiguraci CORS, pokud frontend nahrává. Pokud uživatelé nahrávají přímo z prohlížeče na podepsanou URL, CORS koše musí uvádět vaši produkční origin.
*je přijatelné pouze pro veřejné koše — nikdy pro koše obsahující uživatelská PII.
Politiky RLS na storage.objects
Supabase Storage ukládá metadata souborů v tabulce storage.objects. RLS na této tabulce řídí, kdo může číst, nahrávat, aktualizovat nebo mazat soubory. Bez RLS je vaším jediným ochranou veřejný/privátní příznak koše.
- Potvrďte, že RLS je zapnuté na storage.objects.
SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects';musí vrátittrue. Supabase ho ve výchozím nastavení na nových projektech zapíná; ověřte, že nebylo vypnuto. - Napište politiku SELECT s rozsahem podle
auth.uid()pro privátní koše.CREATE POLICY "users_read_own_files" ON storage.objects FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);. Konvencí je ukládat soubory pod[user-id]/[filename]a používatstorage.foldername()k extrakci vlastníka z cesty. - Napište politiku INSERT, která vynucuje stejnou konvenci cest.
CREATE POLICY "users_upload_own" ON storage.objects FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);. Bez WITH CHECK může ověřený uživatel nahrát do složky jiného uživatele. - Přidejte politiky UPDATE a DELETE, pokud vaše aplikace podporuje úpravy nebo mazání souborů. Každý příkaz potřebuje vlastní politiku. Vynechání DELETE znamená, že ověření uživatelé nemohou odstranit své vlastní soubory; vynechání UPDATE znamená, že přepsání souboru tiše selže.
- Otestujte přístup napříč uživateli ve dvou relacích prohlížeče. Přihlaste se jako Uživatel A, nahrajte soubor, zkopírujte cestu. Přihlaste se jako Uživatel B v jiném prohlížeči, pokuste se získat soubor přes REST API. Odpověď musí být
403nebo404, nikdy200.
-- 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]);Validace nahrávání
Validujte každé nahrávání na straně serveru, i když má koš omezení MIME a velikosti. AI nástroje pro kódování generují ve výchozím nastavení pouze klientskou validaci; ta nechrání nic.
- Znovu zkontrolujte MIME typ na straně serveru ze skutečných bajtů souboru, nikoliv z hlavičky
Content-Type. Použijte knihovnu jakofile-type(Node) nebo magic-byte sniffing. Útočník může tvrditContent-Type: image/jpegu souboru, který je ve skutečnosti polyglotní HTML / JavaScript payload. - Odstraňte EXIF metadata z nahrávaných obrázků. EXIF může obsahovat GPS souřadnice, sériová čísla zařízení a časová razítka. Použijte
sharps.withMetadata(false)neboexif-parserk odstranění před uložením. - Odmítněte SVG, která obsahují tagy
scriptnebo handleryonload. SVG je XML — a mnoho AI generovaných aplikací povoluje nahrávání SVG jako "obyčejný obrázek". PoužijteDOMPurifyna straně serveru nebo nahrávání SVG úplně odmítněte. - Používejte deterministické, neuhodnutelné názvy souborů. Nezachovávejte původní název souboru. Použijte UUID nebo hash obsahu souboru. Původní názvy unikají ("
passport_scan_2024_01_15.jpg") a předvídatelné názvy umožňují enumeraci.
Podepsané URL
Podepsané URL jsou způsob, jakým klienti přistupují k privátním košům. Doba expirace, rozsah koše a co se loguje — to vše záleží.
- Výchozí expiraci podepsané URL nastavte na 1 hodinu nebo méně.
createSignedUrl(path, expiresIn)z Supabase JS SDK přijímá sekundy. Nikdy nepoužívejte hodnoty jako31536000(jeden rok) — URL se stane trvalým polopublickým odkazem. - Nikdy neukládejte podepsané URL do databáze. Generujte čerstvé na straně serveru při každém požadavku. Uložené podepsané URL s 1letou expirací, které unikne přes výpis databáze, uděluje dlouhodobý přístup.
- Logujte generování podepsaných URL, ne pouze nahrávání souborů. Pokud později podezřívate kompromitaci, musíte vědět, kdo vygeneroval kterou URL a kdy. Logujte
auth.uid()+ koš + cestu objektu + časové razítko. - Použijte volbu
downloadAspři obsluze souborů nahraných uživatelem.createSignedUrl(path, expiresIn, { download: '.jpg' })vynutí hlavičkuContent-Disposition: attachment, takže se soubor stáhne místo vykreslení — překazí třídu spouštění HTML / SVG / HTML-v-PDF.
Operační hygiena
Konfigurace úložiště se časem mění. Tyto čtyři operační položky udržují povrch těsně.
- Provádějte audit košů čtvrtletně. Dashboard → Storage → Buckets. Potvrďte, že stav veřejný/privátní a seznamy MIME typů odpovídají tomu, co aplikace očekává. Koše vytvořené "dočasně" se stanou trvalými, pokud je nikdo neodstraní.
- Monitorujte anonymní operace vypisování. Logy úložiště (Dashboard → Logs → Storage) zaznamenávají požadavky
LIST. Skok anonymních požadavků na vypsání proti privátnímu koši znamená, že ho někdo zvenku sonduje. - Nastavte retenční politiku pro efemérní nahrávky. Dočasné koše (náhled obrázku, koncepty nahrávek) by se měly automaticky mazat po 24-72 hodinách přes plánovanou funkci. Neomezené uchovávání je závazek podle povinností minimalizace dat dle GDPR / CCPA.
- Spouštějte FixVibe sken měsíčně. Kontrola
baas.supabase-storage-publicsondu provádí na koše, které odpovídají na anonymníGET+LIST. Přibývají nové koše; staré mění viditelnost — jen průběžné skenování zachytí ten posun.
Další kroky
Spusťte FixVibe sken proti vaší produkční URL — anonymní výpisy úložiště se objeví pod baas.supabase-storage-public. Spárujte tento kontrolní seznam s Skener Supabase RLS pro vrstvu tabulek a Servisní klíč Supabase vystavený v JavaScriptu pro sousedství vystavení klíče. Pro chybné konfigurace úložiště napříč dalšími poskytovateli BaaS viz Skener chybných konfigurací BaaS.
