// docs / baas security / supabase storage
Кантрольны спіс бяспекі сховішча Supabase: 22 пункты
Supabase Storage — гэта тонкая абалонка вакол S3-сумяшчальнага сховішча плюс тая ж мадэль Бяспекі на ўзроўні радкоў, што і ў базе дадзеных. Гэта азначае, што тыя ж пасткі RLS, якія ўплываюць на табліцы, уплываюць на доступ да файлаў — плюс некалькі спецыфічных для сховішча, якія з'яўляюцца, калі ШІ-інструменты кадавання падключаюць загрузкі. Гэты кантрольны спіс — 22 пункты ў пяці раздзелах: канфігурацыя сховішча, палітыкі RLS, праверка загрузкі, падпісаныя URL і эксплуатацыйная гігіена. Кожны можна праверыць менш чым за 15 хвілін.
Кожны пункт ніжэй істотны. Для базавай механікі RLS гл. Сканер Supabase RLS. Для класа раскрыцця ключа, сумежнага са сховішчам, гл. Ключ сэрвіснай ролі Supabase, раскрыты ў JavaScript.
Канфігурацыя сховішча
Пачніце з правільных значэнняў па змаўчанні. Няправільна наладжанае сховішча выцякае файлы, незалежна ад таго, ці правільны ваш RLS.
- Па змаўчанні рабіце кожнае сховішча прыватным. У панэлі Supabase → Storage → Buckets, усталюйце перамыкач Public bucket на off, калі ў вас няма відавочнай прычыны (маркетынгавыя матэрыялы, публічныя аватары без PII). Публічныя сховішчы абыходзяць RLS для аперацый чытання — кожны з імем сховішча можа пералічваць і спампоўваць.
- Усталюйце цвёрды ліміт памеру файла на кожнае сховішча. Dashboard → Bucket settings → File size limit. 50 МБ — гэта разумнае значэнне па змаўчанні для карыстальніцкіх загрузак; павышайце яго наўмысна для відэа / выпадкаў з вялікімі файламі. Без ліміту адна шкодная загрузка можа вычарпаць вашу квоту сховішча або месячную прапускную здольнасць.
- Абмяжуйце дазволеныя MIME-тыпы на кожнае сховішча. Спіс дазволеных MIME-тыпаў — відавочны спіс дазволу, а не блакаванне.
image/jpeg,image/png,image/webpдля сховішчаў толькі для выяў. Ніколі не дазваляйцеtext/html,application/javascriptабоimage/svg+xmlу сховішчы карыстальніцкага кантэнту — яны выконваюцца ў браўзеры пры абслугоўванні праз падпісаны URL. - Выкарыстоўвайце адно сховішча на тып кантэнту, а не адно агульнае сховішча. Налады кожнага сховішча (памер, MIME-тыпы, палітыкі RLS) — гэта дэталізацыя, якая ў вас ёсць. Сховішча
user-avatars, сховішчаdocument-uploadsі сховішчаpublic-assetsпрасцей заблакаваць, чым адно змешанае сховішча. - Праверце канфігурацыю CORS, калі загрузкі ідуць з фронтэнда. Калі карыстальнікі загружаюць напрамую з браўзера на падпісаны URL, CORS сховішча павінен пералічваць ваш прадукцыйны origin.
*прымальны толькі для публічных сховішчаў — ніколі для сховішчаў, якія змяшчаюць карыстальніцкі PII.
Палітыкі RLS на storage.objects
Supabase Storage захоўвае метаданыя файлаў у табліцы storage.objects. RLS на гэтай табліцы кантралюе, хто можа чытаць, загружаць, абнаўляць або выдаляць файлы. Без RLS публічны/прыватны сцяг сховішча — гэта вашая адзіная абарона.
- Пацвердзіце, што RLS уключаны на storage.objects.
SELECT rowsecurity FROM pg_tables WHERE schemaname = 'storage' AND tablename = 'objects';павінен вярнуцьtrue. Supabase уключае яго па змаўчанні на новых праектах; пацвердзіце, што ён не быў адключаны. - Напішыце палітыку SELECT, абмежаваную
auth.uid()для прыватных сховішчаў.CREATE POLICY "users_read_own_files" ON storage.objects FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);. Канвенцыя — захоўваць файлы пад[user-id]/[filename]і выкарыстоўвацьstorage.foldername(), каб вылучыць уладальніка з шляху. - Напішыце палітыку INSERT, якая забяспечвае тую ж канвенцыю шляху.
CREATE POLICY "users_upload_own" ON storage.objects FOR INSERT WITH CHECK (auth.uid()::text = (storage.foldername(name))[1]);. Без WITH CHECK аўтэнтыфікаваны карыстальнік можа загружаць у тэчку іншага карыстальніка. - Дадайце палітыкі UPDATE і DELETE, калі ваша праграма падтрымлівае рэдагаванне або выдаленне файлаў. Кожная каманда патрабуе сваёй палітыкі. Прапуск DELETE азначае, што аўтэнтыфікаваныя карыстальнікі не могуць выдаліць свае ўласныя файлы; прапуск UPDATE азначае, што перазапіс файлаў ціха правальваецца.
- Праверце міжкарыстальніцкі доступ у двух браўзерных сесіях. Увайдзіце як Карыстальнік A, загрузіце файл, скапіюйце шлях. Увайдзіце як Карыстальнік B у іншым браўзеры, паспрабуйце атрымаць файл праз REST API. Адказ павінен быць
403або404, ніколі200.
-- 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]);Праверка загрузкі
Правярайце кожную загрузку на серверы, нават калі сховішча мае абмежаванні MIME і памеру. ШІ-інструменты кадавання генеруюць праверку толькі на кліенце па змаўчанні; гэта нічога не абараняе.
- Паўторна правярайце MIME-тып на серверы з фактычных байтаў файла, а не з загалоўка
Content-Type. Выкарыстоўвайце бібліятэку, такую якfile-type(Node), або нюханне магічных байтаў. Зламыснік можа сцвярджацьContent-Type: image/jpegна файле, які насамрэч з'яўляецца паліглотным HTML / JavaScript карыснай нагрузкай. - Выдаляйце метаданыя EXIF з загружаных выяў. EXIF можа змяшчаць GPS-каардынаты, серыйныя нумары прылад і часавыя меткі. Выкарыстоўвайце
sharpз.withMetadata(false)абоexif-parser, каб выдаліць перад захаваннем. - Адхіляйце SVG, якія змяшчаюць тэгі
scriptабо апрацоўшчыкіonload. SVG — гэта XML — і шмат ШІ-згенераваных праграм дазваляюць загрузкі SVG як "проста выяву". ВыкарыстоўвайцеDOMPurifyна серверы або цалкам адмаўляйцеся ад загрузкі SVG. - Выкарыстоўвайце дэтэрмінаваныя, неўгадваемыя імёны файлаў. Не захоўвайце арыгінальнае імя файла. Выкарыстоўвайце UUID або хэш змесціва файла. Арыгінальныя імёны файлаў выцякаюць ("
passport_scan_2024_01_15.jpg"), а прадказальныя імёны дазваляюць пералічэнне.
Падпісаныя URL
Падпісаныя URL — гэта тое, як кліенты атрымліваюць доступ да прыватных сховішчаў. Тэрмін дзеяння, ахоп сховішча і тое, што логуецца, маюць значэнне.
- Па змаўчанні тэрмін дзеяння падпісанага URL — 1 гадзіна або менш.
createSignedUrl(path, expiresIn)у JS SDK Supabase бярэ секунды. Ніколі не выкарыстоўвайце значэнні накшталт31536000(адзін год) — URL становіцца сталай паўпублічнай спасылкай. - Ніколі не захоўвайце падпісаныя URL у вашай базе дадзеных. Генеруйце свежыя на серверы пры кожным запыце. Захаваны падпісаны URL з 1-гадовым тэрмінам дзеяння, які выцякае праз дамп базы дадзеных, дае доўгатэрміновы доступ.
- Лагуйце генерацыю падпісаных URL, а не толькі загрузкі файлаў. Калі вы падазраяце кампраметацыю пазней, вам трэба ведаць, хто згенераваў які URL і калі. Лагуйце
auth.uid()+ сховішча + шлях да аб'екта + часавую метку. - Выкарыстоўвайце опцыю
downloadAsпры абслугоўванні файлаў, загружаных карыстальнікамі.createSignedUrl(path, expiresIn, { download: '.jpg' })прымусова дадае загаловакContent-Disposition: attachment, каб файл спампоўваўся, а не рэндзерыўся — перамагае клас выканання HTML / SVG / HTML-у-PDF.
Эксплуатацыйная гігіена
Канфігурацыя сховішча дрэйфуе з часам. Гэтыя чатыры эксплуатацыйныя пункты трымаюць паверхню шчыльнай.
- Праводзьце аўдыт сховішчаў штоквартальна. Dashboard → Storage → Buckets. Пацвердзіце публічны/прыватны стан і спісы MIME-тыпаў адпавядаюць таму, што чакае праграма. Сховішчы, створаныя "тэмпарарна", становяцца сталымі, калі ніхто іх не выдаляе.
- Сачыце за ананімнымі аперацыямі спісу. Логі сховішча (Dashboard → Logs → Storage) запісваюць запыты
LIST. Усплёск ананімных запытаў спісу супраць прыватнага сховішча азначае, што нехта зандуе яго звонку. - Усталюйце палітыку захавання для часавых загрузак. Часавыя сховішчы (папярэдні прагляд выявы, чарнавыя загрузкі) павінны аўтаматычна выдаляцца праз 24-72 гадзіны з дапамогай запланаванай функцыі. Бязмежнае захаванне — гэта адказнасць у адпаведнасці з абавязкамі мінімізацыі дадзеных GDPR / CCPA.
- Запускайце сканаванне FixVibe штомесяц. Праверка
baas.supabase-storage-publicзандуе сховішчы, якія адказваюць на ананімныяGET+LIST. Дадаюцца новыя сховішчы; старыя мяняюць бачнасць — толькі бесперапыннае сканаванне ловіць гэты дрэйф.
Наступныя крокі
Запусціце сканаванне FixVibe супраць вашага прадукцыйнага URL — ананімныя спісы сховішчаў з'яўляюцца пад baas.supabase-storage-public. Спалучайце гэты кантрольны спіс з Сканерам Supabase RLS для пласта табліцы і Ключом сэрвіснай ролі Supabase, раскрытым у JavaScript для сумежнасці раскрыцця ключа. Для няправільных налад сховішча сярод іншых пастаўшчыкоў BaaS гл. Сканер няправільных налад BaaS.
