// docs / baas security / supabase storage
Supabasen storage-bucketin tietoturvatarkistuslista: 22 kohtaa
Supabase Storage on ohut käärö S3-yhteensopivan bucketin ympärillä plus sama row-level security -malli kuin tietokannassa. Tämä tarkoittaa, että samat RLS-sudenkuopat, jotka koskevat tauluja, koskevat myös tiedostojen pääsyä — ja muutamia storage-spesifisiä, jotka ilmenevät, kun AI-koodaustyökalut johdottavat lähetyksiä. Tämä tarkistuslista sisältää 22 kohtaa viidessä osiossa: bucket-konfiguraatio, RLS-policyt, lähetysten validointi, allekirjoitetut URL:t ja operatiivinen hygienia. Jokainen on verifioitavissa alle 15 minuutissa.
Jokainen alla oleva kohta on olennainen. Taustalla olevasta RLS-mekaniikasta katso Supabase RLS -skanneri. Storagen viereen kuuluvasta avaintenpaljastumisluokasta katso Supabase service-role-avain paljastunut JavaScriptissä.
Bucketin konfiguraatio
Aloita oikeilla oletuksilla. Virhekonfiguroitu bucket vuotaa tiedostoja riippumatta siitä, onko RLS oikein vai ei.
- Aseta jokainen bucket oletuksena yksityiseksi. Supabase-dashboardissa → Storage → Buckets, aseta Public bucket-kytkin pois päältä, ellei sinulla ole eksplisiittistä syytä (markkinointiresurssit, julkiset avatarit ilman PII:tä). Julkiset bucketit ohittavat RLS:n lukuoperaatioille — kuka tahansa, jolla on bucketin nimi, voi listata ja ladata.
- Aseta kova tiedostokokorajoitus jokaiseen bucketiin. Dashboard → Bucket-asetukset → File size limit. 50 MB on järkevä oletus käyttäjälähetyksille; nosta sitä tietoisesti video-/suuritiedostokäyttötapauksissa. Ilman rajoitusta yksi haitallinen lähetys voi kuluttaa storage-kiintiösi tai kuukauden kaistanleveytesi.
- Rajoita sallitut MIME-tyypit bucket-kohtaisesti. Sallittujen MIME-tyyppien lista — eksplisiittinen allowlist, ei blocklist.
image/jpeg,image/png,image/webpvain kuvia sisältäville bucketeille. Älä koskaan sallitext/html,application/javascripttaiimage/svg+xmlkäyttäjäsisältöbucketissa — ne suoritetaan selaimessa, kun ne tarjoillaan allekirjoitetun URL:n kautta. - Käytä yksi bucket sisältötyyppiä kohden, ei yhtä jaettua bucketia. Bucket-kohtaiset asetukset (koko, MIME-tyypit, RLS-policyt) ovat se granulariteetti, joka sinulla on.
user-avatars-bucket,document-uploads-bucket japublic-assets-bucket on helpompi lukita kuin yksi sekoitettu bucket. - Verifioi CORS-konfiguraatio, jos frontend lähettää. Jos käyttäjät lähettävät suoraan selaimesta allekirjoitettuun URL:ään, bucketin CORSin täytyy listata tuotanto-originisi.
*on hyväksyttävää vain julkisille bucketeille — ei koskaan käyttäjä-PII:tä sisältäville.
RLS-policyt storage.objectsissa
Supabase Storage tallentaa tiedoston metadatan storage.objects-tauluun. RLS tuossa taulussa hallitsee, kuka voi lukea, lähettää, päivittää tai poistaa tiedostoja. Ilman RLS:ää bucketin public/private-lippu on ainoa suojasi.
- Vahvista, että RLS on käytössä storage.objectsissa.
SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects';täytyy palauttaatrue. Supabase ottaa sen oletuksena käyttöön uusissa projekteissa; verifioi, että sitä ei ole poistettu käytöstä. - Kirjoita SELECT-policy, joka on rajattu
auth.uid():hen yksityisille bucketeille.CREATE POLICY "users_read_own_files" ON storage.objects FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);. Konventio on tallentaa tiedostot polun[user-id]/[filename]alle ja käyttäästorage.foldername():ia omistajan poimimiseen polusta. - Kirjoita INSERT-policy, joka pakottaa saman polkukonvention.
CREATE POLICY "users_upload_own" ON storage.objects FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);. Ilman WITH CHECK:iä autentikoitunut käyttäjä voi lähettää toisen käyttäjän kansioon. - Lisää UPDATE- ja DELETE-policyt, jos sovelluksesi tukee tiedostomuokkauksia tai poistoja. Jokainen komento tarvitsee oman policynsä. DELETEn ohittaminen tarkoittaa, että autentikoidut käyttäjät eivät voi poistaa omia tiedostojaan; UPDATEn ohittaminen tarkoittaa, että tiedoston ylikirjoitukset epäonnistuvat hiljaa.
- Testaa ristikkäiskäyttäjäpääsy kahdessa selainsessiossa. Kirjaudu käyttäjänä A, lähetä tiedosto, kopioi polku. Kirjaudu käyttäjänä B toisessa selaimessa, yritä hakea tiedosto REST-API:n kautta. Vastauksen täytyy olla
403tai404, ei koskaan200.
-- 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]);Lähetysten validointi
Validoi jokainen lähetys palvelinpuolella, vaikka bucketissa olisi MIME- ja kokorajoitukset. AI-koodaustyökalut tuottavat oletuksena vain klienttipuolen validoinnin; se ei suojaa mitään.
- Tarkista MIME-tyyppi uudelleen palvelinpuolella tiedoston todellisista tavuista, ei
Content-Type-headerista. Käytä kirjastoa kutenfile-type(Node) tai magic-byte-haistelua. Hyökkääjä voi väittääContent-Type: image/jpegtiedostolle, joka on todellisuudessa polyglotti HTML-/JavaScript-payload. - Strippaa EXIF-metadata ladattaviksi lähetetyistä kuvista. EXIF voi sisältää GPS-koordinaatteja, laitteen sarjanumeroita ja aikaleimoja. Käytä
sharp:ia.withMetadata(false):lla taiexif-parser:ia stripataksesi ennen tallennusta. - Hylkää SVG:t, jotka sisältävät
script-tageja taionload-handlereita. SVG on XML — ja monet AI-generoidut sovellukset sallivat SVG-lähetykset "vain kuvana". KäytäDOMPurify:ia palvelinpuolella tai kiellä SVG-lähetykset kokonaan. - Käytä deterministisiä, arvaamattomia tiedostonimiä. Älä säilytä alkuperäistä tiedostonimeä. Käytä UUID:tä tai tiedoston sisällön hashia. Alkuperäiset tiedostonimet vuotavat ("
passport_scan_2024_01_15.jpg") ja ennustettavat nimet mahdollistavat enumeraation.
Allekirjoitetut URL:t
Allekirjoitetut URL:t ovat tapa, jolla klientit pääsevät yksityisiin bucketteihin. Vanhentumisaika, bucketin rajaus ja se, mitä lokitetaan, ovat tärkeitä.
- Aseta allekirjoitetun URL:n vanhentumisajaksi oletuksena 1 tunti tai vähemmän. Supabase JS SDK:n
createSignedUrl(path, expiresIn)ottaa sekunteja. Älä koskaan käytä arvoja kuten31536000(yksi vuosi) — URL:stä tulee pysyvä puolijulkinen linkki. - Älä koskaan tallenna allekirjoitettuja URL:eja tietokantaasi. Generoi uudet palvelinpuolella jokaisen pyynnön yhteydessä. Tallennettu allekirjoitettu URL 1-vuoden vanhentumisella, joka vuotaa tietokantadumpin kautta, antaa pitkäaikaisen pääsyn.
- Lokita allekirjoitettujen URL:ien generointi, ei vain tiedostojen lähetyksiä. Jos epäilet kompromettointia myöhemmin, sinun täytyy tietää, kuka generoi minkä URL:n ja milloin. Lokita
auth.uid()+ bucket + objektin polku + aikaleima. - Käytä
downloadAs-vaihtoehtoa, kun tarjoilet käyttäjien lähettämiä tiedostoja.createSignedUrl(path, expiresIn, { download: '.jpg' })pakottaaContent-Disposition: attachment-headerin, joten tiedosto ladataan renderöinnin sijaan — kumoaa HTML-/SVG-/HTML-in-PDF-suoritusluokan.
Operatiivinen hygienia
Storage-konfiguraatio ajautuu ajan myötä. Nämä neljä operatiivista kohtaa pitävät pinnan tiukkana.
- Tarkasta bucketit neljännesvuosittain. Dashboard → Storage → Buckets. Vahvista, että public/private-tila ja MIME-tyyppilistat vastaavat sitä, mitä sovellus odottaa. "Väliaikaisesti" luodut bucketit muuttuvat pysyviksi, jos kukaan ei poista niitä.
- Valvo anonyymejä listausoperaatioita. Storage-lokit (Dashboard → Logs → Storage) kirjaavat
LIST-pyynnöt. Anonyymien list-pyyntöjen piikki yksityistä bucketia vastaan tarkoittaa, että joku tutkii sitä ulkopuolelta. - Aseta säilytyspolitiikka lyhytaikaisille lähetyksille. Temp-bucketit (kuvan esikatselu, luonnoslähetykset) tulisi auto-poistaa 24–72 tunnin jälkeen ajastetulla funktiolla. Rajoittamaton säilytys on vastuu GDPR-/CCPA-dataminimointivelvoitteiden alaisuudessa.
- Aja FixVibe-skannaus kuukausittain.
baas.supabase-storage-public-tarkistus tutkii bucketteja, jotka vastaavat anonyymiinGET- +LIST-pyyntöön. Uusia bucketteja lisätään; vanhat vaihtavat näkyvyyttä — vain jatkuva skannaus nappaa ajautumisen.
Seuraavat askeleet
Aja FixVibe-skannaus tuotanto-URL:ääsi vastaan — anonyymit storage-listaukset näkyvät baas.supabase-storage-public:n alla. Yhdistä tämä tarkistuslista artikkeliin Supabase RLS -skanneri taulukerrosta varten ja artikkeliin Supabase service-role-avain paljastunut JavaScriptissä viereistä avaintenpaljastumista varten. Storage-virhekonfiguraatioita muiden BaaS-tarjoajien yli löytyy artikkelista BaaS-virhekonfiguraatioskanneri.
