[{"data":1,"prerenderedAt":350},["ShallowReactive",2],{"blog-uk-supabase-storage-bucket-public":3},{"id":4,"title":5,"body":6,"category":308,"cover":309,"coverAlt":310,"description":311,"draft":312,"extension":313,"faq":314,"image":330,"keywords":331,"meta":338,"navigation":339,"ogTitle":340,"path":341,"published":342,"seo":343,"stem":344,"tldr":345,"updated":342,"__hash__":349},"blog_uk\u002Fblog\u002Fsupabase-storage-bucket-public.md","Ваш бакет Supabase Storage публічний. Чи це проблема?",{"type":7,"value":8,"toc":297},"minimark",[9,13,16,24,29,32,35,38,41,45,48,110,113,116,122,126,129,141,151,154,157,171,175,178,193,196,201,204,211,215,218,224,233,236,240,243,246,249,252,256,284],[10,11,12],"p",{},"Хтось відкрив ваш застосунок, хвилину в ньому покопирсався й надіслав вам\nповідомлення: ваш бакет Supabase Storage публічний, і будь-хто може переглянути\nсписок того, що в ньому лежить.",[10,14,15],{},"Це два окремі твердження. Одне з них, найпевніше, стосується налаштування, яке\nви обрали навмисно й маєте лишити. Друге варте цілого пообіддя.",[10,17,18,19,23],{},"Ось що гайд за гайдом подає неправильно: ",[20,21,22],"strong",{},"публічність і перелічуваність це два\nрізні перемикачі, і тривожний із них не той, який усі радять перемкнути.","\nЗробити бакет приватним закриває перший. Другий це може лишити навстіж\nвідчиненим, а бакет, який ніколи в житті не був публічним, цілком може бути\nперелічуваним сьогодні.",[25,26,28],"h2",{"id":27},"чи-є-публічний-бакет-supabase-storage-проблемою-безпеки","Чи є публічний бакет Supabase Storage проблемою безпеки?",[10,30,31],{},"Сам собою ні. Він означає одну цілком конкретну річ, і дуже часто саме ту, якої\nви й хотіли.",[10,33,34],{},"Позначити бакет публічним означає дати кожному файлу в ньому URL, що працює без\nвходу в систему. У цьому вся функція. Так завантажується аватар під коментарем\nдля людини без облікового запису, так з'являється ваш логотип у листі, так бачить\nфото товару той, хто ще вирішує, чи реєструватися.",[10,36,37],{},"Публічний бакет ближчий до телефонного номера поза довідником, ніж до незамкнених\nдверей. Лінія з'єднає будь-кого, хто набере номер, і немає довідника, де його\nзнайти. Чи це нормально, залежить від одного питання: наскільки легко хтось\nдійде до цього номера, якщо йому його не називали.",[10,39,40],{},"Supabase створює нові бакети приватними й ставить попередження біля перемикача.\nТож публічний бакет це те, що хтось увімкнув: ви або ваш білдер, аби запрацювала\nфункція завантаження файлів.",[25,42,44],{"id":43},"що-насправді-вмикає-перемикач-публічності","Що насправді вмикає перемикач публічності",[10,46,47],{},"Один рядок таблиці нижче, і більше нічого в ній.",[49,50,51,67],"table",{},[52,53,54],"thead",{},[55,56,57,61,64],"tr",{},[58,59,60],"th",{},"Що хтось намагається зробити",[58,62,63],{},"Публічний бакет",[58,65,66],{},"Приватний бакет",[68,69,70,82,92,101],"tbody",{},[55,71,72,76,79],{},[73,74,75],"td",{},"Відкрити файл, точний URL якого вже має",[73,77,78],{},"Спрацює, без входу в систему",[73,80,81],{},"Потрібна політика або підписане посилання",[55,83,84,87,90],{},[73,85,86],{},"Попросити список вмісту бакета",[73,88,89],{},"Лише якщо дозволяє політика",[73,91,89],{},[55,93,94,97,99],{},[73,95,96],{},"Завантажити файл",[73,98,89],{},[73,100,89],{},[55,102,103,106,108],{},[73,104,105],{},"Видалити чи замінити файл",[73,107,89],{},[73,109,89],{},[10,111,112],{},"Власна довідкова сторінка Supabase каже це так ясно, як це взагалі можна сказати:\nпублічний бакет означає, що існує публічний URL, за яким можна завантажити файл,\nа всі інші дії й далі мусять задовольняти політики цього бакета.",[10,114,115],{},"Тобто перемикач це менший важіль, ніж підказує його назва. Три з тих чотирьох\nрядків вирішуються геть в іншому місці, у Storage → Policies, і повідомлення, яке\nви отримали, майже напевно стосувалося другого.",[117,118],"diagram",{"alt":119,"caption":120,"src":121},"Чотири бакети поруч. У кожного є перемикач публічності, вимкнений або ввімкнений, і поле політики, порожнє або заповнене. Два бакети, у полі яких умова називає лише сам бакет, показують усі шість своїх файлів підсвіченими й перекресленими, хоч як стоїть перемикач. Два з порожнім або вузьким полем не показують нічого й позначені галочкою.","Перемикач угорі змінює одну річ. Поле під ним вирішує, чи отримає незнайомець список, і робить це однаково, публічний бакет чи приватний.","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fpublic-and-listable-1600x760.png",[25,123,125],{"id":124},"чому-приватний-бакет-усе-одно-може-бути-перелічуваним","Чому приватний бакет усе одно може бути перелічуваним",[10,127,128],{},"Бо перелічення дозволяє політика доступу, а політика, яку вставляє більшість,\nдозволяє його всім.",[10,130,131,132,136,137,140],{},"Кожне читання зі Storage проходить через Row Level Security на таблиці з назвою\n",[133,134,135],"code",{},"storage.objects",". Перелічити бакет це читання, віднесене до ",[133,138,139],{},"SELECT",", точно так\nсамо як і завантажити файл. Власний швидкий старт Supabase показує політику саме\nтакої форми, звідки зазвичай і беруться копії:",[142,143,149],"pre",{"className":144,"code":146,"language":147,"meta":148},[145],"language-sql","create policy \"Public Access\"\n  on storage.objects for select\n  using ( bucket_id = 'public' );\n","sql","",[133,150,146],{"__ignoreMap":148},[10,152,153],{},"Прочитайте, що там написано. Будь-який запит може читати будь-що в цьому бакеті.\nВін не питає, хто питає, і не питає, чи має файл узагалі стосунок до того, хто\nйого просить. Читання охоплює завантаження файлу, і охоплює видачу списку файлів,\nбо це один і той самий дозвіл у двох капелюхах.",[10,155,156],{},"Перемикач самого бакета сюди ніколи не втручається. Така політика на приватному\nбакеті робить його перелічуваним, а панель і далі цілком правдиво називатиме його\nприватним.",[10,158,159,160,165,166,170],{},"Слово, яке чинить шкоду, це «будь-який». Запит із публічним ключем, що їде\nвсередині коду вашого застосунку, задовольняє цю політику без жодних зусиль, і\n",[161,162,164],"a",{"href":163},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","цей ключ і має бути доступним для читання всім",",\nщо якраз і є причиною, чому працювати мала б політика. Це та сама форма, що й у\nсусідньої проблеми, де\n",[161,167,169],{"href":168},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Row Level Security увімкнено, і вона все одно все пропускає",".",[25,172,174],{"id":173},"що-дає-комусь-список-ваших-файлів","Що дає комусь список ваших файлів",[10,176,177],{},"Насамперед назви. А це значно більше, ніж звучить.",[10,179,180,181,184,185,188,189,192],{},"Назви файлів зазвичай описують вміст, бо людина обирала їх, думаючи про те, що\nвсередині: ",[133,182,183],{},"rahunok-berezen-acme.pdf",", ",[133,186,187],{},"pasport-perednia.jpg",",\n",[133,190,191],{},"zarplata-final-v2.xlsx",". Список таких назв це непоганий переказ вашого бізнесу, а\nйого довжина приблизно каже, скільки у вас клієнтів. Якщо бакет ще й публічний,\nкожна назва в тому списку є робочим посиланням.",[10,194,195],{},"Повернімося до телефонного номера. Бути поза довідником чогось варте рівно доти,\nдоки довідник не вийшов друком, а після того вже ніколи не мало значення,\nнаскільки важко було вгадати номер.",[117,197],{"alt":198,"caption":199,"src":200},"Дві половини. Ліворуч запит до публічного шляху об'єктів дістає один файл із восьми; решту сім намальовано пунктирними контурами, яких запит так і не знаходить. Праворуч запит до шляху переліку повертає всі вісім суцільними рядками.","Без переліку незнайомець мусить якось дійти до назви файлу. З переліком йому видають кожну назву, яку ви маєте.","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fguess-or-list-1600x700.png",[10,202,203],{},"Виявляється це щоразу буденно. Документ, що належить одному клієнту, опиняється\nперед іншим. Хтось називає вам назву файлу, якої не мав звідки знати. Теку із\nзавантаженнями копіюють цілком автоматичним сканером, що читав усі проєкти\nSupabase, які міг знайти.",[10,205,206,207,170],{},"Наше безкоштовне сканування просить у вашого Storage перелік, використовуючи лише\nтой ключ, що вже є в коді вашого застосунку, і каже, які бакети відповіли вмістом.\nВоно читає назви й ніколи не завантажує файл. Триває близько 20 секунд і не\nпотребує облікового запису: ",[161,208,210],{"href":209},"\u002F#scan","просканувати застосунок",[25,212,214],{"id":213},"як-зрозуміти-який-із-двох-випадків-у-вас","Як зрозуміти, який із двох випадків у вас",[10,216,217],{},"Дві перевірки в панелі Supabase, і друга стосується того, про що повідомлення\nйшлося насправді.",[10,219,220,223],{},[20,221,222],{},"Storage → Buckets."," Публічні позначені як публічні. Про кожен запитайте себе,\nчи справді кожен окремий файл у ньому це те, що ви показали б незнайомцю. Не\nбільшість файлів. Кожен, включно з тим, що потрапить туди наступного тижня з\nфункції, якої ви ще не збудували.",[10,225,226,229,230,232],{},[20,227,228],{},"Storage → Policies."," Прочитайте кожну політику ",[133,231,139],{},", що стосується бакета.\nУмова, яка згадує лише назву бакета, дозволяє читати його будь-кому. Умова, що\nпорівнює власника файлу з тим, хто робить запит, виконує справжню роботу.\nПорожній список політик на приватному бакеті означає, що не читається взагалі\nнічого, і це суворо й безпечно.",[10,234,235],{},"Якщо ваш застосунок мусить показати приватний файл потрібній людині, інструментом\nдля цього є підписане посилання: ваш сервер просить у Supabase URL, який працює\nзадану кількість хвилин, а потім перестає. Так файл лишається приватним і все\nодно потрапляє на сторінку.",[25,237,239],{"id":238},"коли-публічність-і-є-правильною-відповіддю","Коли публічність і є правильною відповіддю",[10,241,242],{},"Частіше, ніж зазвичай визнає стаття про безпеку, і це варто сказати.",[10,244,245],{},"Якщо файл призначений для всіх, публічність правильна, а обхідний шлях купує вам\nповільніший застосунок і більше коду для підтримки. Аватари, логотипи, обкладинки,\nусе, що має бачити відвідувач без входу в систему: у публічний бакет, і більше про\nце не думайте.",[10,247,248],{},"Єдине, що варто зробити навіть там, це лишити перелічення вимкненим. Публічний\nбакет з аватарами це функція. Той самий бакет, що видає повний список усіх, хто\nбодай колись завантажив аватар, це вже інша річ, і ви її не замовляли.",[10,250,251],{},"Якщо файл належить одній конкретній людині, він іде в приватний бакет із\nполітикою, яка перевіряє, хто питає, і потрапляє на сторінку через підписане\nпосилання. Перевірка зводиться до одного питання: для кого цей файл? Для всіх чи\nдля одного названого облікового запису.",[25,253,255],{"id":254},"що-зробити-цього-тижня","Що зробити цього тижня",[257,258,259],"key-takeaways",{},[260,261,262,266,275,278,281],"ul",{},[263,264,265],"li",{},"Відкрийте Storage → Buckets і випишіть, які з них публічні. Про кожен вирішіть, чи тримає він файли для всіх, чи файли для однієї людини.",[263,267,268,269,271,272,274],{},"Прочитайте кожну політику ",[133,270,139],{}," на ",[133,273,135],{},". Умова, що називає лише бакет, видає список файлів будь-кому; саме вона зробила правдивим отримане вами повідомлення.",[263,276,277],{},"Перенесіть усе, що належить одному користувачеві, у приватний бакет і віддавайте через підписані посилання, які спливають самі.",[263,279,280],{},"Перестаньте називати завантажені файли за їхнім вмістом. Випадковий ідентифікатор нічого не коштує й робить так, що витеклий список видає набагато менше, ніж видав би.",[263,282,283],{},"Робіть резервну копію Storage окремо від бази даних. Ваші завантаження не лежать ні в коді, ні в таблицях Postgres, тож ніщо з того, що копіює ці двоє, не копіює ваші файли.",[10,285,286,287,291,292,296],{},"Відкрийте Storage → Policies у своєму проєкті й прочитайте, що там є, перш ніж\nчіпати бодай один перемикач. Саме той екран вирішує, чи була правдивою друга\nполовина отриманого вами повідомлення.\n",[161,288,290],{"href":289},"\u002Fchecklist","Десятихвилинний чекліст безпеки"," охоплює це поряд з рештою того, що\nщойно запущений застосунок зазвичай лишає відкритим, а якщо бакет таки виявився\nдоступним для читання, то\n",[161,293,295],{"href":294},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","що незнайомець дістає у вашій базі даних","\nбуде наступним для читання, адже політика, яка видає список файлів, має ту саму\nформу, що й та, яка видає таблицю.",{"title":148,"searchDepth":298,"depth":298,"links":299},3,[300,302,303,304,305,306,307],{"id":27,"depth":301,"text":28},2,{"id":43,"depth":301,"text":44},{"id":124,"depth":301,"text":125},{"id":173,"depth":301,"text":174},{"id":213,"depth":301,"text":214},{"id":238,"depth":301,"text":239},{"id":254,"depth":301,"text":255},"Основи безпеки","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcover-1200x630.png","Документи всередині контейнера. Смуга закриває більшу частину отвору й обривається раніше, лишаючи чотири з них у прогалині.","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.",false,"md",[315,318,321,324,327],{"q":316,"a":317},"Мені сказали, що мій бакет Supabase Storage публічний. Чи робити його приватним?","Не раніше, ніж ви дізнаєтеся, що в ньому лежить. Публічні бакети існують не просто так: фото профілів, логотипи, зображення товарів і все інше, що ваш застосунок показує відвідувачу без входу в систему. Для таких файлів публічність і є правильним налаштуванням. Для рахунків, документів, експортів чи будь-чого, що належить одній конкретній людині, вона неправильна, і тоді вам потрібен приватний бакет плюс підписані посилання. Питання ніколи не стояло так, чи публічність погана. Воно стоїть так: чи саме ці файли призначалися для будь-кого, хто попросить.",{"q":319,"a":320},"Яка різниця між публічним бакетом і перелічуваним?","Публічність вирішує, чи відкриється файл тому, хто вже має його URL. Перелічуваність вирішує, чи може незнайомець попросити у вашого проєкту весь вміст бакета й отримати відповідь. Ці дві речі налаштовуються в різних місцях панелі Supabase, і саме друга перетворює здогад на покажчик.",{"q":322,"a":323},"Чи може хтось вгадати URL файлів у моєму публічному бакеті?","Це цілком залежить від того, як їх називає ваш застосунок. Якщо він завантажує їх під первісною назвою або під чимось охайним на кшталт rahunok-4.pdf, то так, і зусиль на це майже не треба. Якщо він завантажує їх під довгим випадковим ідентифікатором, вгадування стає непрактичним. Саме тому перелічення важить так багато: воно прибирає крок вгадування повністю.",{"q":325,"a":326},"Як завадити перелічувати мій бакет?","Перелічення проходить через політику Row Level Security на таблиці storage.objects, тож виправляють його саме там, а не на самому бакеті. Відкрийте Storage → Policies у панелі Supabase і прочитайте кожну політику SELECT, що стосується бакета. Та, єдина умова якої це назва бакета, дозволяє будь-якому запиту читати цей бакет разом зі списком файлів. Звузьте її так, щоб вона порівнювала файл із тим, хто його просить, або приберіть її й видавайте підписані посилання зі свого сервера.",{"q":328,"a":329},"Чи охоплює резервна копія бази даних завантажені файли?","Ні. Storage живе поза вашою базою Postgres, тож копія бази містить рядки, що вказують на ваші файли, і жодного з самих файлів. Відновлення дасть вам таблицю, повну посилань на те, чого вже немає. Завантажені файли треба копіювати окремо, і більшість людей дізнається про це того дня, коли це має значення.","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",[332,333,334,335,336,337],"публічний бакет supabase storage","безпека публічного бакета supabase","політика доступу supabase storage","перелік файлів у бакеті supabase","зробити бакет supabase приватним","підписане посилання supabase",{},true,"Чи є публічний бакет Supabase проблемою?","\u002Fblog\u002Fsupabase-storage-bucket-public","2026-08-23",{"title":5,"description":311},"blog\u002Fsupabase-storage-bucket-public",[346,347,348],"Публічний бакет Supabase Storage означає одну річ: той, хто має URL файлу, відкриє його без входу в систему. Про те, чи побачить він решту вмісту, це не каже нічого.","Перелічення дозволяє політика доступу, а не перемикач публічності, тож приватний бакет може бути перелічуваним, а публічний ні.","Саме перелічення варто виправити сьогодні, бо воно позбавляє незнайомця клопоту вгадувати бодай одну назву файлу.","e6kwZA9NCzByF7eBFJv50Cc_YYyyD4y-bNPF4Z9N1dU",1787826051139]