FixVibe

// docs / baas security / supabase storage

Supabase storage bucket-ի անվտանգության ստուգաթերթ․ 22 կետ

Supabase Storage-ը S3-համատեղելի bucket-ի բարակ թաղանթ է գումարած նույն Row-Level Security մոդելը, ինչ որ տվյալների բազան։ Դա նշանակում է, որ նույն RLS թակարդները, որոնք ազդում են table-ների վրա, ազդում են ֆայլերի մուտքի վրա — և մի քանի storage-specific թակարդներ, որոնք ի հայտ են գալիս, երբ AI-ի կոդավորման գործիքները լարում են upload-ները։ Այս ստուգաթերթը 22 կետ է հինգ բաժնում․ bucket-ի կարգավորում, RLS policy-ներ, upload-ի վավերացում, signed URL-ներ, և գործառնական հիգիենա։ Յուրաքանչյուրն ստուգելի է 15 րոպեից պակաս ժամանակում։

Ստորև յուրաքանչյուր կետ էական է։ Հիմքում ընկած RLS մեխանիզմների համար տես Supabase RLS սկաներ։ Storage-ին հարակից բանալու-բացահայտման դասի համար տես Supabase service role key-ը բացահայտված JavaScript-ում։

Bucket-ի կարգավորում

Սկսիր ճիշտ լռելյայններից։ Սխալ կարգավորված bucket-ը արտահոսում է ֆայլեր՝ անկախ նրանից, թե քո RLS-ը ճիշտ է, թե ոչ։

  1. Լռելյայն դարձրու յուրաքանչյուր bucket մասնավոր։ Supabase Dashboard → Storage → Buckets-ում, Public bucket toggle-ը դարձրու անջատված, քանի դեռ չունես հստակ պատճառ (մարքեթինգային ակտիվներ, հանրային avatar-ներ առանց PII)։ Հանրային bucket-ները շրջանցում են RLS-ը ընթերցման գործողությունների համար — ցանկացած ոք bucket-ի անունով կարող է թվարկել և ներբեռնել։
  2. Սահմանիր ֆայլի չափի կոշտ սահման յուրաքանչյուր bucket-ի վրա։ Dashboard → Bucket settings → File size limit։ 50 MB-ը ողջամիտ լռելյայն է օգտատերերի upload-ների համար. գիտակցորեն բարձրացրու վիդեո / մեծ ֆայլի օգտագործման դեպքերի համար։ Առանց սահմանի, մեկ վնասակար upload-ը կարող է սպառել քո storage quota-ն կամ քո ամսական bandwidth-ը։
  3. Սահմանափակիր թույլատրված MIME-տիպերը bucket-ի համար։ Allowed MIME types ցուցակ — բացահայտ allowlist, ոչ blocklist։ image/jpeg, image/png, image/webp միայն-պատկեր bucket-ների համար։ Երբեք չթույլատրես text/html, application/javascript կամ image/svg+xml օգտատերերի-բովանդակության bucket-ում — դրանք գործարկվում են զննարկիչում, երբ սպասարկվում են signed URL-ի միջոցով։
  4. Օգտագործիր մեկ bucket մեկ բովանդակության տեսակի համար, ոչ թե մեկ ընդհանուր bucket։ Bucket-ի կարգավորումները (չափ, MIME-տիպեր, RLS policy-ներ) գրանուլյարությունն են, որ ունես։ user-avatars bucket-ը, document-uploads bucket-ը և public-assets bucket-ը ավելի հեշտ է փակել, քան մեկ խառը bucket։
  5. Ստուգիր CORS կարգավորումը, եթե ֆրոնտէնդը upload է անում։ Եթե օգտատերերն ուղղակիորեն upload են անում զննարկիչից signed URL-ին, bucket-ի CORS-ը պետք է թվարկի քո production origin-ը։ *-ը ընդունելի է միայն հանրային bucket-ների համար — երբեք օգտատերերի PII պարունակող bucket-ների համար։

RLS policy-ներ storage.objects-ի վրա

Supabase Storage-ը պահում է ֆայլերի մետատվյալները storage.objects table-ում։ RLS-ն այդ table-ի վրա վերահսկում է, թե ով կարող է կարդալ, upload անել, թարմացնել կամ ջնջել ֆայլեր։ Առանց RLS-ի, bucket-ի public/private flag-ն քո միակ պաշտպանությունն է։

  1. Հաստատիր, որ RLS-ը միացված է storage.objects-ի վրա։ SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects'; պետք է վերադարձնի true։ Supabase-ն այն լռելյայն միացնում է նոր նախագծերում. ստուգիր, որ այն չի անջատվել։
  2. Գրիր SELECT policy, որ սահմանված է auth.uid()-ով մասնավոր bucket-ների համար։ CREATE POLICY "users_read_own_files" ON storage.objects FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);։ Կանոնն այն է, որ պահել ֆայլերը [user-id]/[filename] տակ և օգտագործել storage.foldername()՝ ուղուց սեփականատիրոջը հանելու համար։
  3. Գրիր INSERT policy, որ պարտադրում է նույն ուղու կանոնը։ CREATE POLICY "users_upload_own" ON storage.objects FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);։ Առանց WITH CHECK-ի, վավերացված օգտատերը կարող է upload անել մեկ այլ օգտատիրոջ թղթապանակ։
  4. Ավելացրու UPDATE և DELETE policy-ներ, եթե քո հավելվածն աջակցում է ֆայլի խմբագրումներ կամ ջնջումներ։ Յուրաքանչյուր հրաման ունի իր սեփական policy-ի կարիքը։ DELETE-ը բաց թողնելը նշանակում է, որ վավերացված օգտատերերը չեն կարող հեռացնել իրենց սեփական ֆայլերը. UPDATE-ը բաց թողնելը նշանակում է, որ ֆայլի վերագրումներն լուռ ձախողվում են։
  5. Ստուգիր օգտատերերի միջև մուտքը երկու զննարկչի սեսիաներում։ Մուտք գործիր որպես Օգտատեր Ա, upload արա ֆայլ, պատճենիր ուղին։ Մուտք գործիր որպես Օգտատեր Բ մեկ այլ զննարկչում, փորձիր ֆայլը ստանալ REST API-ի միջոցով։ Պատասխանը պետք է լինի 403 կամ 404, երբեք 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]);

Upload-ի վավերացում

Վավերացրու յուրաքանչյուր upload սերվերային կողմից, նույնիսկ երբ bucket-ը MIME-ի և չափի սահմանափակումներ ունի։ AI-ի կոդավորման գործիքները լռելյայն գեներացնում են միայն-հաճախորդի վավերացում. դա ոչինչ չի պաշտպանում։

  1. Կրկին ստուգիր MIME տիպը սերվերային կողմից ֆայլի փաստացի բայթերից, ոչ թե Content-Type header-ից։ Օգտագործիր գրադարան՝ file-type (Node) կամ magic-byte sniffing-ը։ Հարձակվողը կարող է հայտարարել Content-Type: image/jpeg այնպիսի ֆայլի վրա, որ իրականում polyglot HTML / JavaScript payload է։
  2. Հանիր EXIF մետատվյալները upload արված պատկերներից։ EXIF-ը կարող է պարունակել GPS կոորդինատներ, սարքի սերիական համարներ և ժամանակացույցեր։ Օգտագործիր sharp .withMetadata(false)-ով կամ exif-parser՝ պահելուց առաջ հանելու համար։
  3. Մերժիր SVG-ները, որոնք պարունակում են script tag-եր կամ onload handler-ներ։ SVG-ն XML է — և շատ AI-գեներացված հավելվածներ թույլ են տալիս SVG upload-ներ որպես «պարզապես պատկեր»։ Օգտագործիր DOMPurify սերվերային կողմից կամ ընդհանրապես հրաժարվիր SVG upload-ից։
  4. Օգտագործիր որոշակիորեն չկռահելի ֆայլերի անուններ։ Մի պահպանիր սկզբնական ֆայլի անունը։ Օգտագործիր UUID կամ ֆայլի բովանդակության hash։ Սկզբնական ֆայլի անունները արտահոսում են («passport_scan_2024_01_15.jpg») և կանխատեսելի անունները հնարավորություն են տալիս թվարկման։

Signed URL-ներ

Signed URL-ները այն են, ինչպես հաճախորդները մուտք են ունենում մասնավոր bucket-ներին։ Ժամկետի սպառումը, bucket-ի շրջանակը և թե ինչ է գրառվում՝ կարևոր է։

  1. Լռելյայն signed-URL ժամկետը 1 ժամ կամ պակաս դարձրու։ Supabase JS SDK-ի createSignedUrl(path, expiresIn)-ը վերցնում է վայրկյաններ։ Երբեք մի օգտագործիր այնպիսի արժեքներ, ինչպիսին 31536000-ն է (մեկ տարի) — URL-ը դառնում է մշտական կիսա-հանրային հղում։
  2. Երբեք մի պահպանիր signed URL-ները քո տվյալների բազայում։ Գեներացրու թարմ URL-ներ սերվերային կողմից յուրաքանչյուր հարցման ժամանակ։ Պահպանված signed URL՝ 1 տարի ժամկետով, որ արտահոսում է տվյալների բազայի dump-ի միջոցով, շնորհում է երկարատև մուտք։
  3. Գրառիր signed-URL-ի գեներացումը, ոչ միայն ֆայլի upload-ները։ Եթե հետագայում կասկածում ես կոմպրոմիսի, պետք է իմանաս, թե ով է գեներացրել որ URL-ը երբ։ Գրառիր auth.uid() + bucket + object ուղի + ժամանակացույց։
  4. Օգտագործիր downloadAs տարբերակը, երբ սպասարկում ես օգտատերերի upload արած ֆայլեր։ createSignedUrl(path, expiresIn, { download: '.jpg' })-ը պարտադրում է Content-Disposition: attachment header, որպեսզի ֆայլը ներբեռնվի՝ ռենդրման փոխարեն — հաղթահարում է HTML / SVG / HTML-in-PDF գործարկման դասը։

Գործառնական հիգիենա

Storage-ի կարգավորումը ժամանակի ընթացքում շեղվում է։ Այս չորս գործառնական կետերը մակերեսը պահում են ամուր։

  1. Աուդիտ արա bucket-ները եռամսյակային։ Dashboard → Storage → Buckets։ Հաստատիր, որ public/private վիճակը և MIME-տիպերի ցուցակները համապատասխանում են այն բանին, ինչ հավելվածն ակնկալում է։ «Ժամանակավորապես» ստեղծված bucket-ները դառնում են մշտական, եթե ոչ ոք չհանի դրանք։
  2. Հետևիր անանուն list գործողություններին։ Storage log-երը (Dashboard → Logs → Storage) գրառում են LIST հարցումները։ Անանուն list հարցումների աճ մասնավոր bucket-ի դեմ նշանակում է, որ ինչ-որ մեկը այն ստուգում է դրսից։
  3. Սահմանիր պահպանման policy անցողիկ upload-ների համար։ Ժամանակավոր bucket-ները (պատկերի նախադիտում, սևագիր upload-ներ) պետք է ինքնաջնջվեն 24-72 ժամ հետո՝ պլանավորված ֆունկցիայի միջոցով։ Անժամկետ պահպանումը պարտավորություն է GDPR / CCPA տվյալների-նվազեցման պարտավորությունների ներքո։
  4. Գործարկիր FixVibe սկան ամսական։ baas.supabase-storage-public ստուգումը ստուգում է bucket-ները, որոնք պատասխանում են անանուն GET + LIST-ին։ Նոր bucket-ներ ավելանում են. հները փոխում են տեսանելիությունը — միայն շարունակական սկանավորումը գտնում է շեղումը։

Հաջորդ քայլեր

Գործարկիր FixVibe սկան քո production URL-ի դեմ — անանուն storage listings հայտնվում են baas.supabase-storage-public-ի տակ։ Զուգակցիր այս ստուգաթերթը Supabase RLS սկաներ-ի հետ table շերտի համար և Supabase service role key-ը բացահայտված JavaScript-ում-ի հետ՝ բանալու-բացահայտման հարակցության համար։ Այլ BaaS մատակարարների storage-ի սխալ կարգավորումների համար տես BaaS սխալ կարգավորման սկաներ։

// սկանավորիր քո baas մակերեսը

Գտիր բաց table-ը, քանի դեռ դա ուրիշը չի արել։

Մուտքագրիր production URL-ը։ FixVibe-ը թվարկում է BaaS մատակարարները, որոնց հետ խոսում է քո հավելվածը, ֆինգերփրինթ է անում իրենց հանրային endpoint-ները, և հայտնում, թե ինչ կարող է կարդալ կամ գրել չհաստատված հաճախորդը։ Անվճար, առանց տեղադրման, առանց քարտի։

  • Անվճար փաթեթ — 3 սկան ամսական, առանց գրանցման քարտի։
  • Պասիվ BaaS fingerprinting — տիրույթի հաստատում չի պահանջվում։
  • Supabase, Firebase, Clerk, Auth0, Appwrite և ավելին։
  • AI fix prompts յուրաքանչյուր գտածոյի համար — տեղադրիր Cursor / Claude Code-ում։
Գործարկիր անվճար BaaS սկան

գրանցում չի պահանջվում

Supabase storage bucket-ի անվտանգության ստուգաթերթ․ 22 կետ — Docs · FixVibe