FixVibe

// 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.

  1. 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.
  2. 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.
  3. Rajoita sallitut MIME-tyypit bucket-kohtaisesti. Sallittujen MIME-tyyppien lista — eksplisiittinen allowlist, ei blocklist. image/jpeg, image/png, image/webp vain kuvia sisältäville bucketeille. Älä koskaan salli text/html, application/javascript tai image/svg+xml käyttäjäsisältöbucketissa — ne suoritetaan selaimessa, kun ne tarjoillaan allekirjoitetun URL:n kautta.
  4. 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 ja public-assets-bucket on helpompi lukita kuin yksi sekoitettu bucket.
  5. 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.

  1. Vahvista, että RLS on käytössä storage.objectsissa. SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects'; täytyy palauttaa true. Supabase ottaa sen oletuksena käyttöön uusissa projekteissa; verifioi, että sitä ei ole poistettu käytöstä.
  2. 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.
  3. 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.
  4. 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.
  5. 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 403 tai 404, ei koskaan 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]);

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.

  1. Tarkista MIME-tyyppi uudelleen palvelinpuolella tiedoston todellisista tavuista, ei Content-Type-headerista. Käytä kirjastoa kuten file-type (Node) tai magic-byte-haistelua. Hyökkääjä voi väittää Content-Type: image/jpeg tiedostolle, joka on todellisuudessa polyglotti HTML-/JavaScript-payload.
  2. Strippaa EXIF-metadata ladattaviksi lähetetyistä kuvista. EXIF voi sisältää GPS-koordinaatteja, laitteen sarjanumeroita ja aikaleimoja. Käytä sharp:ia .withMetadata(false):lla tai exif-parser:ia stripataksesi ennen tallennusta.
  3. Hylkää SVG:t, jotka sisältävät script-tageja tai onload-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.
  4. 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ä.

  1. 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 kuten 31536000 (yksi vuosi) — URL:stä tulee pysyvä puolijulkinen linkki.
  2. Ä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.
  3. 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.
  4. Käytä downloadAs-vaihtoehtoa, kun tarjoilet käyttäjien lähettämiä tiedostoja. createSignedUrl(path, expiresIn, { download: '.jpg' }) pakottaa Content-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.

  1. 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ä.
  2. 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.
  3. 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.
  4. Aja FixVibe-skannaus kuukausittain. baas.supabase-storage-public-tarkistus tutkii bucketteja, jotka vastaavat anonyymiin GET- + 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.

// skannaa baas-pintasi

Löydä avoin taulu ennen kuin joku muu ehtii.

Liitä tuotanto-URL. FixVibe tunnistaa sovelluksesi käyttämät BaaS-tarjoajat, sormenjälkitarkistaa niiden julkiset päätepisteet ja raportoi, mitä tuntematon asiakas voi lukea tai kirjoittaa. Ilmainen, ei asennusta, ei korttia.

  • Ilmaistaso — 3 skannausta/kk, ei korttia rekisteröitymisessä.
  • Passiivinen BaaS-sormenjälkitunnistus — ei domain-verifiointia tarvita.
  • Supabase, Firebase, Clerk, Auth0, Appwrite ja muita.
  • AI-korjauskehotteet jokaisesta löydöstä — liitä takaisin Cursoriin / Claude Codeen.
Aja ilmainen BaaS-skannaus

rekisteröitymistä ei vaadita

Supabasen storage-bucketin tietoturvatarkistuslista: 22 kohtaa — Docs · FixVibe