[{"data":1,"prerenderedAt":935},["ShallowReactive",2],{"blog-uk-aws-access-key-exposed-in-frontend":3,"blog-index-uk":406},{"id":4,"title":5,"body":6,"category":363,"cover":364,"coverAlt":365,"description":366,"draft":367,"extension":368,"faq":369,"image":383,"keywords":384,"meta":393,"navigation":394,"ogTitle":395,"path":396,"published":397,"seo":398,"stem":399,"tldr":400,"updated":397,"__hash__":405},"blog_uk\u002Fblog\u002Faws-access-key-exposed-in-frontend.md","Відкритий у фронтенді ключ AWS це не те саме, що ключ OpenAI",{"type":7,"value":8,"toc":350},"minimark",[9,18,21,26,39,45,59,65,69,72,79,85,91,97,100,104,107,110,116,119,128,132,135,138,141,150,155,159,162,171,198,209,217,221,224,227,238,241,245,251,260,280,290,307,310,314,337],[10,11,12,13,17],"p",{},"Хтось відкриває ваш застосунок у браузері, натискає F12 і знаходить рядок, що\nпочинається з ",[14,15,16],"code",{},"AKIA",", просто у вашому коді фронтенду. Або GitHub пише вам, що\nкоміт, який ви відправили в березні, несе облікові дані AWS. Порада, яка\nприходить разом з обома випадками, завжди однакова: ротуйте ключ. Для\nбільшості ключів це майже вся відповідь.",[10,19,20],{},"Ось та частина, яку путівник за путівником розуміє неправильно. Ключ доступу\nAWS, відкритий у вашому фронтенді, це не ключ, який витрачає гроші. Це ключ,\nякий відчиняє речі, і ці двоє ламаються в різні боки. Ключ, який тільки\nвитрачає, це корпоративна картка: хтось набирає рахунок, ви блокуєте картку, а\nзбиток це число, яке можна прочитати у виписці. Ключ, який відчиняє речі, це\nв’язка від складу. До чого він дотягнеться, залежить від того, що написали на\nньому під час виготовлення, і це читається на одному екрані вашої консолі AWS.",[22,23,25],"h2",{"id":24},"що-означає-akia-на-початку-ключа","Що означає AKIA на початку ключа?",[10,27,28,29,31,32,35,36,38],{},"Це позначка довготривалого ключа доступу, який належить або користувачеві у\nвашому акаунті, або кореневому входу акаунта. AWS записує цей префікс у\nвласному довіднику ідентифікаторів: ",[14,30,16],{}," для ключів доступу і ",[14,33,34],{},"ASIA"," для\nтимчасових, які видає сервіс токенів. Тобто перші чотири символи кажуть вам,\nз яким різновидом ви маєте справу, і ",[14,37,16],{}," це різновид без терміну дії. Він\nпрацює, доки хтось його не вимкне.",[10,40,41,42,44],{},"Облікові дані AWS це два рядки, і запит потребує обох, щоб бути підписаним.\nПерший це ідентифікатор ключа доступу, та частина, що починається з ",[14,43,16],{},".\nДругий це таємний ключ доступу, довший рядок без жодного префікса спереду.\nСам ідентифікатор не підписує нічого.",[10,46,47,48,50,51,54,55,58],{},"Це варто перевірити, перш ніж вирішувати, наскільки поганий цей ранок, бо воно\nзмінює відповідь. Якщо ваш бандл несе рядок ",[14,49,16],{}," і нічого схожого на його\nтаємну половину, відвідувач, який прочитав вашу сторінку, забрав ім’я ключа, а\nне ключ. На практиці ці двоє подорожують разом, бо те, що поклало в браузер\nодин, поклало обидва: пара змінних середовища з іменами ",[14,52,53],{},"AWS_ACCESS_KEY_ID"," і\n",[14,56,57],{},"AWS_SECRET_ACCESS_KEY",", прочитана кодом, який мав працювати на сервері.",[60,61],"diagram",{"alt":62,"caption":63,"src":64},"Два значення одне над одним ліворуч: коротке бірюзове з написом AKIA і довше під ним, вміст якого намальовано як затерті блоки. Обидва сходяться в одну стрілку до документа з печаткою у формі ключа, позначеного галочкою. Під розділювальною лінією саме лише значення AKIA веде до хрестика.","Обидві половини разом підписують запит. Сам ідентифікатор це ім’я, а ім’я не відчиняє нічого.","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Ftwo-strings-one-signature-1600x640.png",[22,66,68],{"id":67},"що-хтось-може-зробити-з-моїм-ключем-доступу-aws","Що хтось може зробити з моїм ключем доступу AWS?",[10,70,71],{},"Те, що дозволяють його дозволи, і нічого понад те. Тож відповідей три.",[10,73,74,78],{},[75,76,77],"strong",{},"Що він може прочитати?"," Кожен бакет S3, який перелічує політика, і кожен\nоб’єкт усередині, зокрема ті, на які ви ніколи нізвідки не посилалися. Бакет,\nпро який нічого у вашому застосунку не згадує, не схований від облікових\nданих, які можуть його перелічити.",[10,80,81,84],{},[75,82,83],{},"Що він може записати?"," Ті самі місця, і це та половина, про яку забувають.\nКлюч, який уміє писати, уміє також перезаписувати і видаляти, а файл, замінений\nна місці, виглядає точно як той, що ви завантажили, доки хтось його не\nвідкриє.",[10,86,87,90],{},[75,88,89],{},"Що він може запустити?"," Ось це з лічильником. Політика, достатньо широка,\nщоб підняти обчислення, піднімає обчислення, а воно рахує погодинно, доки\nпрацює. Ніщо в браузерній копії ключа не обмежує, якої частини вашого акаунта\nвін сягає; політика це єдина межа, яка існує.",[10,92,93,94,96],{},"Найгірша версія цього це ключ, виготовлений для кореневого входу акаунта. AWS\nпише у власних настановах про кореневого користувача, що той має необмежений\nдоступ до всіх сервісів AWS, ресурсів і даних про рахунки, і радить не\nстворювати йому ключів доступу взагалі. Якщо ключ на вашій сторінці\nпочинається з ",[14,95,16],{}," і належить кореневому користувачеві, відкритим є весь\nакаунт, а не один бакет.",[10,98,99],{},"Тож не вгадуйте нічого з цього. Відкрийте IAM, знайдіть користувача, якому\nналежить ключ, і прочитайте прив’язані до нього політики. Це один екран, і він\nвідповідає на всі три питання вище.",[22,101,103],{"id":102},"чи-досить-просто-ротувати-його","Чи досить просто ротувати його?",[10,105,106],{},"Деактивуйте відкритий ключ сьогодні і не ставте заміну на те саме місце.",[10,108,109],{},"Деактивація це правильний перший крок, і вона м’якша, ніж звучить. AWS\nдозволяє користувачеві тримати до двох активних ключів доступу одночасно, і це\nіснує саме для того, щоб заміна піднялася до того, як старий опуститься.\nДеактивація лишає ключ на місці вимкненим, і його можна ввімкнути назад;\nвидалення незворотне, а таємну половину видаленого ключа не відновити. Тож\nдеактивуйте, подивіться, що зламається, і видаляйте потім.",[10,111,112,113,115],{},"Чого це не завершує, так це створити новий ключ і вставити його туди, де був\nстарий. Витік ніколи не був насправді про те конкретне значення. Він був про\nбраузер, який тримає облікові дані без терміну дії, і все, що завантажує ваша\nсторінка, завантажує кожен відвідувач. Свіжий рядок ",[14,114,16],{}," у тому самому\nбандлі повертається як та сама знахідка при наступному скануванні.",[10,117,118],{},"AWS каже це прямо у власному посібнику з аудиту безпеки, там про мобільні\nзастосунки: вони ніколи не повинні містити вбудовані ключі доступу, навіть\nзашифровані. Бандл браузера читається легше за бінарник застосунку, тож та\nсама відповідь діє і тут, і коштує чужій людині менше роботи.",[10,120,121,122,127],{},"Якщо ви вже знайшли ключ у публічному місці, порядок роботи має значення, і\n",[123,124,126],"a",{"href":125},"\u002Fblog\u002Fapi-key-leaked-what-to-do","що робити, коли ключ API витік",", викладає цей\nпорядок для ключів будь-якого ґатунку.",[22,129,131],{"id":130},"що-натомість-робить-presigned-url","Що натомість робить presigned URL",[10,133,134],{},"Він дозволяє браузеру зробити одну дію з одним файлом, не тримаючи жодних\nоблікових даних.",[10,136,137],{},"Ваш власний сервер лишає ключ доступу собі, там, де відвідувач не може його\nпрочитати. Коли вашій сторінці треба покласти файл у S3 або дістати звідти\nодин, вона просить ваш сервер, і ваш сервер підписує адресу саме для цього\nоб’єкта і саме для цієї дії та віддає її назад. Браузер користується адресою і\nне отримує з нею нічого більше. AWS описує presigned URL як тимчасовий доступ\nдо об’єктів S3 без облікових даних AWS, і той самий механізм покриває і\nзавантаження вниз, і вивантаження вгору.",[10,139,140],{},"Повернімося до складу. Presigned URL це зустріти кур’єра на порозі саме з тією\nкоробкою, по яку він приїхав, замість віддати йому в’язку і сподіватися, що він\nїї знайде. Те, що кур’єр забирає, перестає працювати, коли його годинник\nдобігає кінця.",[10,142,143,144,146,147,149],{},"Для випадку, коли кожна авторизована людина дістається до власних файлів, AWS\nзнову вказує в інший бік: його настанови про захист ключів доступу кажуть, що\nмобільні застосунки мають використовувати Amazon Cognito для керування\nособами, а не вбудовувати ключі доступу. Те, що Cognito дає браузеру, це\nтимчасові облікові дані, різновид ",[14,145,34],{}," з початку цієї статті, які за якийсь\nчас перестають працювати самі. Копія, зіскоблена з вашої сторінки у вівторок,\nуже мертва в середу, і це єдина властивість, якої ключ ",[14,148,16],{}," не має.",[60,151],{"alt":152,"caption":153,"src":154},"Два шляхи намальовано один над одним. Угорі браузер із ключем поруч, стрілка і стелаж із вісьмома файлами на двох полицях. Унизу той самий браузер, стрілка до сервера, який тримає ключ, і ще одна стрілка до одного файла з циферблатом годинника поруч.","Верхній шлях кладе у браузер щось, що діє на кожен файл, завтра так само, як сьогодні. Нижній дає йому один файл і строк.","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fkey-or-url-1600x700.png",[22,156,158],{"id":157},"як-перевірити-чи-мій-застосунок-віддає-ключ-aws","Як перевірити, чи мій застосунок віддає ключ AWS?",[10,160,161],{},"Шукайте в тому, що завантажив браузер, а не в тому, що лежить у проєкті. Це\nдва різні файли, і важить той, який отримують ваші відвідувачі.",[10,163,164,167,168,170],{},[75,165,166],{},"У браузері."," Відкрийте опублікований сайт, натисніть F12 і пошукайте ",[14,169,16],{},"\nу завантаженому JavaScript. Chrome і Edge шукають одразу в усіх завантажених\nфайлах із панелі Sources.",[10,172,173,176,177,179,180,54,182,184,185,188,189,192,193,197],{},[75,174,175],{},"У проєкті."," Пошукайте ",[14,178,16],{},", ",[14,181,53],{},[14,183,57],{},". Потім пошукайте два префікси, які кладуть значення у\nбандл навмисно, ",[14,186,187],{},"VITE_"," і ",[14,190,191],{},"NEXT_PUBLIC_",", і прочитайте кожне значення за ними.\n",[123,194,196],{"href":195},"\u002Fblog\u002Fvite-and-next-public-env-vars","Чому ці два префікси публікують усе, що називають",",\nце механіка за більшістю таких випадків, і це правило збірки, якого ніхто не\nнабирав помилково.",[10,199,200,203,204,208],{},[75,201,202],{},"Ззовні."," Наше безкоштовне сканування читає ваш опублікований сайт так, як це\nзробила б чужа людина, і повідомляє, які облікові дані воно бачить у тому, що\nви віддали, зокрема й цей. Воно триває близько 20 секунд і не потребує акаунта:\n",[123,205,207],{"href":206},"\u002Fsecurity-scanner","просканувати застосунок безкоштовно",".",[10,210,211,212,216],{},"Серед усіх застосунків, які ми сканували, це рідкісна знахідка: ключ доступу\nAWS трапився в 9 з 31 056 застосунків, де ця перевірка дійшла до кінця. Значно\nчастіше трапляються ключі Google, які зазвичай нормальні, і ключі OpenAI, які\nзазвичай ні.\n",[123,213,215],{"href":214},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Що насправді витікає із застосунків, зроблених так",",\nставить їх усі поруч із числами.",[22,218,220],{"id":219},"що-ключ-робив-поки-був-назовні","Що ключ робив, поки був назовні",[10,222,223],{},"Відкрийте історію подій CloudTrail і відфільтруйте її за ідентифікатором ключа\nдоступу.",[10,225,226],{},"Історія подій увімкнена в кожному акаунті AWS без жодних налаштувань, вона\nтримає останні 90 днів і не коштує нічого додатково. Кожен запис несе\nідентифікатор ключа, який зробив виклик, тож ви можете перечитати, що робив\nваш. Це відповідає на питання про конфігурацію: створений бакет, змінена\nполітика, доданий користувач.",[10,228,229,230,233,234,237],{},"Далі йде та частина, яку варто знати, перш ніж іти дивитися. Історія тримає\nподії ",[75,231,232],{},"management",". Прочитати об’єкт із S3 це подія ",[75,235,236],{},"data",", і AWS прямо\nкаже, що trails не журналюють їх за замовчуванням і що події data взагалі не\nз’являються в історії. Увімкнення записує від того моменту вперед.",[10,239,240],{},"Тож чесне прочитання таке. Якщо ключем змінювали ваш акаунт, журнал вам\nпокаже. Якщо ним завантажували вміст бакета, журнал, найімовірніше, не покаже,\nі ви вирішуєте, що казати клієнтам, розуміючи, що це могло статися.",[22,242,244],{"id":243},"як-утримати-ключ-поза-наступною-збіркою","Як утримати ключ поза наступною збіркою",[10,246,247,250],{},[75,248,249],{},"Облікові дані вирушають у браузер під час збірки, тож пильнувати треба\nнаступне розгортання."," Ключ, який ви прибираєте сьогодні, повертається того\nдня, коли хтось додає функцію з S3 і просить агента її підключити.",[10,252,253],{},[75,254,255,259],{},[123,256,258],{"href":257},"\u002Fwebsite-monitoring","Reeve Monitor"," перечитує ваш опублікований сайт за вас:",[261,262,263,267,274,277],"ul",{},[264,265,266],"li",{},"усі дев’ять перевірок щогодини, для до трьох застосунків",[264,268,269,270,273],{},"повідомлення, коли результат ",[75,271,272],{},"змінюється",", щоб ключ, який з’явився у вівторок, не чекав, доки ви заглянете",[264,275,276],{},"чи застосунок відповідає, кожні 60 секунд",[264,278,279],{},"щомісячний звіт про побачене",[10,281,282],{},[75,283,284,285,289],{},"Якщо ваш застосунок тримає дані у проєкті Supabase,\n",[123,286,288],{"href":287},"\u002Fsupabase-backups","Reeve Care"," зберігає копію і цього:",[261,291,292,295,298,301,304],{},[264,293,294],{},"зашифрована копія вашої бази Supabase щоночі, складена там, куди ваш проєкт не дістає",[264,296,297],{},"кожна копія перевірена, перш ніж її зарахувати, підрахунком рядків у кожній таблиці",[264,299,300],{},"відновлення в один клік, коли воно знадобиться",[264,302,303],{},"а також ваші завантажені файли, щойно ви під’єднаєте облікові дані Storage",[264,305,306],{},"усе, що робить Monitor",[10,308,309],{},"Кожна з тих дев’яти перевірок описує, до чого може дотягнутися чужа людина.\nКопія бази за вчорашню ніч відповідає на інше питання, на те, що саме хтось уже\nзмінив, поки ключ був назовні.",[22,311,313],{"id":312},"що-зробити-цього-тижня","Що зробити цього тижня",[315,316,317],"key-takeaways",{},[261,318,319,325,328,331,334],{},[264,320,321,322,324],{},"Відкрийте опублікований сайт, натисніть F12 і пошукайте ",[14,323,16],{}," у завантаженому JavaScript. Це той файл, який мають ваші відвідувачі, і лише він важить.",[264,326,327],{},"Якщо знайшли, деактивуйте його в IAM сьогодні. Деактивація оборотна і діє одразу; видалення ні, і таємну половину не відновити.",[264,329,330],{},"Прочитайте політики, прив’язані до користувача ключа, перш ніж вирішувати, наскільки це серйозно. Що він читає, що пише і що запускає це три окремі відповіді.",[264,332,333],{},"Замініть схему, а не значення. Ваш сервер тримає ключ і підписує presigned URL для одного об’єкта, або Amazon Cognito дає браузеру тимчасові облікові дані, які спливають самі.",[264,335,336],{},"Відфільтруйте історію подій CloudTrail за ключем за останні 90 днів. Вона покаже, що ключ налаштував, і не покаже, які файли він читав, якщо події data не були ввімкнені заздалегідь.",[10,338,339,340,344,345,349],{},"Почніть із пошуку через F12, бо він за хвилину вирішує, чи є у вас проблема\nвзагалі. Якщо щось знайдеться,\n",[123,341,343],{"href":342},"\u002Fchecklist","десятихвилинний чеклист безпеки"," покриває решту того, що\nщойно запущений застосунок зазвичай лишає відчиненим, а\n",[123,346,348],{"href":347},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","перенесення секрету в edge function","\nце схема для кожного ключа, якому ніколи не слід було бути на сторінці.",{"title":351,"searchDepth":352,"depth":352,"links":353},"",3,[354,356,357,358,359,360,361,362],{"id":24,"depth":355,"text":25},2,{"id":67,"depth":355,"text":68},{"id":102,"depth":355,"text":103},{"id":130,"depth":355,"text":131},{"id":157,"depth":355,"text":158},{"id":219,"depth":355,"text":220},{"id":243,"depth":355,"text":244},{"id":312,"depth":355,"text":313},"Основи безпеки","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcover-1200x630.png","Сторінка коду застосунку з коротким підсвіченим значенням і довгим прихованим, ключ лежить навскіс на її кутку, а позаду стелаж із файлами.","Ключ доступу AWS, відкритий у вашому фронтенді, читає і пише ваше сховище. Рішення зазвичай presigned URL, а не новий ключ.",false,"md",[370,373,375,378,380],{"q":371,"a":372},"Чи буває безпечно класти ключі AWS у код фронтенду?","Ні. AWS каже це у власному посібнику з аудиту безпеки, говорячи про мобільні застосунки: застосунок ніколи не повинен містити вбудовані ключі доступу, навіть зашифровані. Бандл браузера читається легше за бінарник застосунку, тож та сама відповідь діє і тут, і коштує чужій людині менше роботи. Якщо ваша сторінка справді має дістатися до S3, передбачені шляхи це presigned URL, підписаний вашим власним сервером, або тимчасові облікові дані від Amazon Cognito, які спливають самі.",{"q":68,"a":374},"Рівно те, що дозволяють його дозволи, і саме тому єдиної відповіді немає. Ключ, прив’язаний до користувача з доступом на читання одного бакета, читає цей бакет. Ключ, прив’язаний до адміністратора, робить усе, що робить адміністратор, зокрема запускає машини з погодинною оплатою. Ключ кореневого користувача акаунта це найгірший випадок, бо AWS пише, що кореневий користувач має необмежений доступ до всіх сервісів, ресурсів і даних про рахунки. Відкрийте IAM і прочитайте політики, прив’язані до ключа, перш ніж вирішувати, наскільки хвилюватися.",{"q":376,"a":377},"Що таке presigned URL?","Довга URL-адреса, яка дозволяє браузеру зробити одну дію з одним файлом у S3 протягом визначеної кількості секунд, не тримаючи жодних облікових даних AWS. Ваш власний сервер тримає ключ і підписує цю адресу на запит. AWS описує presigned URL як тимчасовий доступ до об’єктів S3 без облікових даних AWS, і вони працюють і для завантаження вниз, і для вивантаження вгору.",{"q":158,"a":379},"Шукайте в тому, що завантажив ваш браузер, а не в тому, що лежить у проєкті. Відкрийте опублікований сайт, натисніть F12 і пошукайте AKIA у завантаженому JavaScript. Потім пошукайте у проєкті AKIA, AWS_ACCESS_KEY_ID і AWS_SECRET_ACCESS_KEY, а також будь-яке ім’я змінної, що починається на VITE_ або NEXT_PUBLIC_ і містить таке значення, бо саме ці префікси й кладуть значення у бандл.",{"q":381,"a":382},"Мій ключ AWS на GitHub. Що тепер?","Спершу деактивуйте його в IAM, це оборотно і діє одразу, а потім створіть заміну для сервера, якому він був потрібен. Прибрати ключ із коду не закриває нічого, бо старе значення лишається в історії комітів і в кожному клоні, який хтось зробив. Після цього відкрийте історію подій CloudTrail і відфільтруйте за ключем, щоб побачити, що він робив.","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",[385,386,387,388,389,390,391,392],"ключ доступу aws відкритий у фронтенді","ключ aws у фронтенді","витік ключа доступу aws","ключ akia відкритий","aws secret access key у javascript","облікові дані aws на клієнті","чи безпечні ключі aws у react","ключ aws на github",{},true,"Ключ доступу AWS відкритий у вашому фронтенді?","\u002Fblog\u002Faws-access-key-exposed-in-frontend","2026-10-12",{"title":5,"description":366},"blog\u002Faws-access-key-exposed-in-frontend",[401,402,403,404],"Ключ доступу AWS, відкритий у вашому фронтенді, це інша проблема, ніж ключ, який уміє лише витрачати гроші. До чого він дотягнеться, вирішують його дозволи.","Запит до AWS підписують два рядки: ідентифікатор, що починається з `AKIA`, і таємна половина. Один без одної не підписує нічого.","Новий ключ, вставлений на те саме місце, це та сама знахідка з іншим значенням. Рішення це presigned URL, щоб браузер не тримав жодних облікових даних.","Ми знайшли такий у 9 з 31 056 просканованих застосунків, де ця перевірка дійшла до кінця.","mgyKP9mqdDQvZrNyWHYXYDZZ3br3A4RwntFE0OLZ5v4",[407,413,419,425,431,437,443,449,455,461,467,474,480,486,492,498,504,510,516,522,528,534,540,546,552,558,564,570,576,577,583,589,594,600,606,612,617,623,629,635,641,647,653,659,665,671,676,682,688,694,700,706,712,718,723,729,735,741,747,753,759,765,771,777,783,789,795,801,807,813,818,824,830,836,842,848,854,860,866,872,878,884,890,896,901,907,913,919,924,930],{"path":408,"title":409,"description":410,"published":411,"category":363,"image":412,"draft":367},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\": пояснення","Supabase \"max client connections reached\": у пулера немає місця ще для одного клієнта. Ліміт визначає порт у вашому рядку підключення.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":414,"title":415,"description":416,"published":417,"category":363,"image":418,"draft":367},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Помилка Supabase: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\": вхід через Google вимкнено у вашому проєкті Supabase. Як увімкнути та виправити redirect_uri_mismatch.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":420,"title":421,"description":422,"published":423,"category":363,"image":424,"draft":367},"\u002Fblog\u002Fviolates-foreign-key-constraint","Помилка Supabase \"violates foreign key constraint\" під час вставки","Supabase \"insert or update on table violates foreign key constraint\": ваш рядок посилається на рядок, якого немає. Який, чому і як це виправити.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":426,"title":427,"description":428,"published":429,"category":363,"image":430,"draft":367},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Помилка Supabase \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": обовʼязковий стовпець прийшов порожнім. Звідки взявся null і як це виправити.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":432,"title":433,"description":434,"published":435,"category":363,"image":436,"draft":367},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": куди поділася сесія","\"Auth session missing!\" означає, що supabase-js не знайшла жодної сесії й навіть не спитала Supabase. Куди поділася сесія і як це виправити.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":438,"title":439,"description":440,"published":441,"category":363,"image":442,"draft":367},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": ніхто не ввійшов","\"invalid claim: missing sub claim\": Supabase Auth отримав справжній токен без жодного користувача, ключ проєкту замість сесії.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":444,"title":445,"description":446,"published":447,"category":363,"image":448,"draft":367},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": справжня причина","\"Failed to send a request to the Edge Function\": браузер не отримав відповіді, яку можна прочитати. Його консоль каже, чому, і чи ваша функція запускалася.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":450,"title":451,"description":452,"published":453,"category":363,"image":454,"draft":367},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Чому Supabase перенаправляє посилання з листів на localhost:3000","Якщо Supabase перенаправляє на localhost:3000, Site URL так і не змінили або вашої адреси немає в Redirect URLs. Як виправити і якої маски уникати.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":456,"title":457,"description":458,"published":459,"category":363,"image":460,"draft":367},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","Supabase \"Email link is invalid or has expired\" на новому посиланні","На посиланні, надісланому хвилину тому, \"Email link is invalid or has expired\" у Supabase зазвичай означає, що поштовий фільтр використав його першим.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":462,"title":463,"description":464,"published":465,"category":363,"image":466,"draft":367},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\": пояснення","Supabase \"canceling statement due to statement timeout\": запит перевищив ліміт своєї ролі, 3 секунди для відвідувача. Спершу перевірте політику RLS.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":468,"title":469,"description":470,"published":471,"category":472,"image":473,"draft":367},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" у Supabase і що зникає разом","\"Database error deleting user\" у Supabase: ваша база відмовилася видаляти. Причина в логах, а виправлення вирішує, що ще буде видалено.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":475,"title":476,"description":477,"published":478,"category":363,"image":479,"draft":367},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" у Supabase","Вебхук Stripe в Edge Function Supabase пише \"No signatures found matching the expected signature\"? Причин дві. Не вимикайте перевірку.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":481,"title":482,"description":483,"published":484,"category":363,"image":485,"draft":367},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" у Supabase: три причини","Supabase відповідає \"Invalid login credentials\" на неправильний пароль, невідому пошту й акаунт Google. Як зрозуміти, що саме.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":487,"title":488,"description":489,"published":490,"category":363,"image":491,"draft":367},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": справжня помилка","\"Edge Function returned a non-2xx status code\" означає, що ваша функція Supabase відповіла помилкою. Ось де прочитати справжню.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":493,"title":494,"description":495,"published":496,"category":363,"image":497,"draft":367},"\u002Fblog\u002Fcertificate-not-trusted","Сертифікат не довірений: три причини, крім закінчення строку","Сертифікат не довірений, хоча дата в порядку? Він називає іншу адресу, підписав сам себе або в його ланцюжку бракує ланки. Як зрозуміти, що саме.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":499,"title":500,"description":501,"published":502,"category":363,"image":503,"draft":367},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": що в лапках","Supabase \"invalid input syntax for type uuid\" означає, що застосунок надіслав щось, що не є id. Прочитайте лапки, притримайте запит, залиште колонку.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":505,"title":506,"description":507,"published":508,"category":363,"image":509,"draft":367},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\": пояснення","Supabase \"duplicate key value violates unique constraint\": значення вже зайняте. Знайдіть стовпець, оберіть виправлення й сховайте значення від очей.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":511,"title":512,"description":513,"published":514,"category":363,"image":515,"draft":367},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\", хоча таблиця на місці","Supabase \"relation does not exist\" або PGRST205: жодна таблиця не має такої назви в цій схемі. Чотири перевірки, і на що зважити, відкриваючи схему.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":517,"title":518,"description":519,"published":520,"category":363,"image":521,"draft":367},"\u002Fblog\u002Fsupabase-function-not-found","Supabase PGRST202: \"Could not find the function in the schema cache\"","Supabase \"Could not find the function in the schema cache\" показує назви аргументів, які надіслав ваш застосунок. Порівняйте їх із функцією.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":523,"title":524,"description":525,"published":526,"category":363,"image":527,"draft":367},"\u002Fblog\u002Fsupabase-schema-cache-column-error","Supabase PGRST204: \"Could not find the column in the schema cache\"","Supabase \"Could not find the column in the schema cache\" зазвичай означає, що назва не збігається. Чотири перевірки і рядок для перезавантаження.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":529,"title":530,"description":531,"published":532,"category":363,"image":533,"draft":367},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\": два ліміти, один код помилки","Supabase \"Email Rate Limit Exceeded\" обмежує кожен лист вашого проєкту: 2 на годину з вбудованим відправником. Що враховується і як підняти ліміт.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":535,"title":536,"description":537,"published":538,"category":363,"image":539,"draft":367},"\u002Fblog\u002Fsupabase-users-logged-out","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 причини","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" виводить ваших користувачів із системи. Три причини і як лог Auth їх розрізняє.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":541,"title":542,"description":543,"published":544,"category":363,"image":545,"draft":367},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": три причини","Supabase \"permission denied for schema public\" означає, що бракує GRANT на схему. Що його прибрало і який рядок його повертає.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":547,"title":548,"description":549,"published":550,"category":363,"image":551,"draft":367},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": три речі, які це може означати","Supabase \"Bucket not found\" означає одне з трьох: публічне посилання на приватний бакет, неточну назву або не той проєкт.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":553,"title":554,"description":555,"published":556,"category":363,"image":557,"draft":367},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: який ключ перестав працювати?","Помилка Supabase invalid JWT — це PGRST301: підписаний токен не пройшов перевірку. У новому проєкті йдеться про сесію, а не про ключ API.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":559,"title":560,"description":561,"published":562,"category":363,"image":563,"draft":367},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" майже завжди означає нуль","Supabase повертає PGRST116, \"JSON object requested, multiple (or no) rows returned\", коли запит нічого не знайшов. Прихований рядок має вигляд відсутнього.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":565,"title":566,"description":567,"published":568,"category":363,"image":569,"draft":367},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" у Supabase: де шукати","\"Database error saving new user\" означає, що щось причеплене до вашої реєстрації в Supabase впало. Справжня помилка лежить у ваших логах.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":571,"title":572,"description":573,"published":574,"category":363,"image":575,"draft":367},"\u002Fblog\u002Fwhat-is-supabase","Що таке Supabase? База даних, яку обрав ваш білдер","Що таке Supabase: база даних, вхід і сховище файлів за вашим застосунком. Supabase тримає сервери, а правила про те, хто читає ваші рядки, ваші.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":396,"title":5,"description":366,"published":397,"category":363,"image":383,"draft":367},{"path":578,"title":579,"description":580,"published":581,"category":363,"image":582,"draft":367},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" при вивантаженні","\"New row violates row-level security policy for table objects\" означає, що вашому вивантаженню бракує правила insert. Публічний бакет його не додає.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":584,"title":585,"description":586,"published":587,"category":363,"image":588,"draft":367},"\u002Fblog\u002Fbase44-security-scan","Сканування безпеки Base44: те, що бачить лише воно","Сканування безпеки Base44 перевіряє сім видів проблем зсередини. Ось половина, яку читає тільки воно, і половина, на яку воно ніколи не дивиться.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":125,"title":590,"description":591,"published":592,"category":363,"image":593,"draft":367},"Ваш API-ключ витік. Порядок дій","API-ключ витік, і ви не знаєте, що робити першим. Не кожен ключ у вашому фронтенді є витоком, а порядок важить більше за швидкість.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":595,"title":596,"description":597,"published":598,"category":363,"image":599,"draft":367},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" без вимкнення RLS","\"Infinite recursion detected in policy for relation\" означає, що ваша policy запитала таблицю, яку вона захищає. Ось як розірвати коло.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":601,"title":602,"description":603,"published":604,"category":363,"image":605,"draft":367},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" у Supabase, і хибне виправлення","\"No API key found in request\" означає, що запит дійшов до Supabase без ключа. Більшість відповідей натомість вказують на правила вашої бази.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":607,"title":608,"description":609,"published":610,"category":363,"image":611,"draft":367},"\u002Fblog\u002Fis-base44-safe","Чи безпечний Base44? Дані 5 442 застосунків","Чи безпечний Base44? Ми прогнали дев’ять перевірок на 5 442 робочих застосунках Base44. Майже всі отримали B з причин, яких власник ніколи не обирав.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":347,"title":613,"description":614,"published":615,"category":363,"image":616,"draft":367},"Сховати ключ API: перенесіть його в Supabase Edge Function","Сховати ключ API означає прибрати його з браузера, а Supabase Edge Function це найменше місце, куди його покласти. Два кроки поруч важать більше.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":618,"title":619,"description":620,"published":621,"category":363,"image":622,"draft":367},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Чи відкритий ваш файл .env? Дванадцять шляхів для перевірки","Чи відкритий ваш файл .env на вашому власному вебсервері? Дванадцять адрес скажуть це за хвилину, а влучання означає, що все в ньому вже публічне.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":624,"title":625,"description":626,"published":627,"category":363,"image":628,"draft":367},"\u002Fblog\u002Fis-v0-safe","Безпека v0: усі 1 790 просканованих застосунків v0 отримали A","Безпека v0 на 1 790 живих застосунках v0: усі отримали A. Лише 17 згадували базу даних, і саме це здебільшого вимірює оцінка A.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":630,"title":631,"description":632,"published":633,"category":363,"image":634,"draft":367},"\u002Fblog\u002Fis-bolt-safe","Чи безпечний Bolt? Що показали 1 123 застосунки Bolt","Чи безпечний Bolt? Ми прогнали 1 123 живі застосунки Bolt через дев’ять перевірок. Хостинг був чистим. Знахідки: ключі й відкриті таблиці в самих застосунках.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":636,"title":637,"description":638,"published":639,"category":363,"image":640,"draft":367},"\u002Fblog\u002Fis-supabase-down-or-your-app","Supabase не працює чи проблема у вашому застосунку? Як розрізнити","Supabase не працює чи зламався ваш застосунок? Пауза, повна база й ваша власна помилка виглядають однаково. Чотири перевірки їх розрізняють.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":642,"title":643,"description":644,"published":645,"category":363,"image":646,"draft":367},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","Чи шифрує Supabase мої дані? Так. Ось від чого це захищає","Чи шифрує Supabase дані? Так: AES-256 у стані спокою, TLS під час передавання, SOC 2 та ISO 27001. Що покриває кожне і який витік не зупиняє жодне.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":648,"title":649,"description":650,"published":651,"category":363,"image":652,"draft":367},"\u002Fblog\u002Fsupabase-free-plan-limits","Ліміти безкоштовного тарифу Supabase і що стається на кожному","Ліміти безкоштовного тарифу Supabase: 500 МБ бази, 5 ГБ egress і жодних резервних копій. Що стається на кожній межі і що змінює Pro за $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":654,"title":655,"description":656,"published":657,"category":472,"image":658,"draft":367},"\u002Fblog\u002Ftest-your-supabase-backup","Перевірте резервну копію Supabase до того, як вона знадобиться","Як перевірити резервну копію Supabase: відновити в тестовий проєкт, порахувати рядки, увійти й знайти рядок, якого бракує обрізаному файлу.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":660,"title":661,"description":662,"published":663,"category":472,"image":664,"draft":367},"\u002Fblog\u002Fsupabase-backup-github-action","Безкоштовна резервна копія Supabase через GitHub Action і підступ","Резервна копія Supabase через GitHub Action безкоштовна й годиться багатьом застосункам. Робочий процес, потрібний рядок підключення та egress.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":666,"title":667,"description":668,"published":669,"category":472,"image":670,"draft":367},"\u002Fblog\u002Fdownload-your-supabase-backup","Чому ви не можете завантажити резервну копію Supabase","Завантажити резервну копію Supabase на сучасному проєкті не вийде: щоденна копія там фізична. Як це перевірити і як тримати власну копію.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":672,"title":673,"description":674,"published":669,"category":363,"image":675,"draft":367},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": бракує GRANT","З 30 жовтня нова таблиця в Supabase відповідає \"permission denied for table\", доки ви не дасте доступ. Лист показує лише половину виправлення.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":677,"title":678,"description":679,"published":680,"category":363,"image":681,"draft":367},"\u002Fblog\u002Fopen-api-endpoint-exposed","Чи є відкритий API-ендпоінт проблемою безпеки? Читайте JSON","Ваше сканування позначило відкритий API-ендпоінт. Чи це важливо, залежить від того, що повернулося, і більшість знайдених належали платформі.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":683,"title":684,"description":685,"published":686,"category":363,"image":687,"draft":367},"\u002Fblog\u002Flovable-security-scan","Сканування безпеки Lovable: чого воно не доведе","Сканування безпеки Lovable: що перевіряють Quick scan і Deep scan, коли запускається кожне, і єдине, чого не доведе жодне сканування зсередини.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":689,"title":690,"description":691,"published":692,"category":472,"image":693,"draft":367},"\u002Fblog\u002Fsupabase-backup-auth-users","Чому у вашому дампі Supabase немає користувачів","Запустіть supabase db dump окремо і отримаєте форму вашої бази та жодного її рядка, без схеми auth, у якій живуть ваші користувачі.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":695,"title":696,"description":697,"published":698,"category":363,"image":699,"draft":367},"\u002Fblog\u002Fdomain-and-certificate-expiry","Домен закінчився, сайт лежить: що буде далі","Ваш домен закінчився і сайт лежить. Ось який годинник уже пішов, чому прострочений сертифікат це менша з двох бід, і як перевірити обидва.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":701,"title":702,"description":703,"published":704,"category":363,"image":705,"draft":367},"\u002Fblog\u002Fis-lovable-safe","Чи безпечний Lovable? Що показали 18 554 застосунки Lovable","Чи безпечний Lovable? Ми прогнали 18 554 живі застосунки Lovable через дев’ять перевірок. Платформа виявилася найчистішою з п’яти. Знахідки були в застосунках.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":707,"title":708,"description":709,"published":710,"category":363,"image":711,"draft":367},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Чек-лист безпеки для vibe coding, у девʼяти перевірках","Чек-лист безпеки для vibe coding із девʼяти пунктів, кожен з яких будь-хто може перевірити у вашому живому застосунку ззовні, і кожен має тест на один рядок.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":713,"title":714,"description":715,"published":716,"category":363,"image":717,"draft":367},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Секретний ключ Stripe у фронтенді може рухати гроші","Секретний ключ Stripe, відкритий у вашому фронтенді, може повертати кошти, списувати й читати кожну картку клієнта. А ключ pk_live_ там і має бути.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":195,"title":719,"description":720,"published":721,"category":363,"image":722,"draft":367},"Змінні оточення Vite відкриті: префікс означає опублікувати це","Змінні оточення Vite відкриті у вашому застосунку, бо так просив префікс. VITE_ і NEXT_PUBLIC_ означають опублікувати це, а ШІ, який їх додав, не знав ціни.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":724,"title":725,"description":726,"published":727,"category":363,"image":728,"draft":367},"\u002Fblog\u002Fbase44-source-maps","Безпека Base44: що позначає скан і що з цього виправляти вам","Безпека Base44 на 5 438 просканованих застосунках: три знахідки майже на кожному належать платформі, source map є бейджем Base44, а ваша частина коротка.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":730,"title":731,"description":732,"published":733,"category":363,"image":734,"draft":367},"\u002Fblog\u002Fis-cursor-ai-safe","Чи безпечний Cursor AI? Редактор, код і опублікований застосунок","Чи безпечний Cursor AI? Три запитання в одному пошуку: що Cursor зберігає, у чому помиляється його код і чи відкритий застосунок, який ви опублікували.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":736,"title":737,"description":738,"published":739,"category":363,"image":740,"draft":367},"\u002Fblog\u002Fis-replit-safe","Чи безпечний Replit? Що ми знайшли в 3 042 живих застосунках Replit","Чи безпечний Replit? Ми прогнали 3 042 живі застосунки Replit через дев’ять зовнішніх перевірок. Знахідки були в опублікованому застосунку, а не в хостингу.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":742,"title":743,"description":744,"published":745,"category":472,"image":746,"draft":367},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: у копії бази даних немає жодного файлу","Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":748,"title":749,"description":750,"published":751,"category":472,"image":752,"draft":367},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery у Supabase: ціна та межі","Point-in-time recovery у Supabase відмотує базу на будь-яку секунду за останній тиждень. Коштує $100 на місяць понад Pro і покриває лише базу даних.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":754,"title":755,"description":756,"published":757,"category":472,"image":758,"draft":367},"\u002Fblog\u002Fsupabase-project-paused-recover","Проєкт Supabase на паузі? Ваші дані нікуди не зникли","Supabase поставив ваш проєкт на паузу після тижня без активності. Нічого не видалено, кнопка Restore стоїть поруч із назвою, і у вас є рік, щоб натиснути.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":760,"title":761,"description":762,"published":763,"category":363,"image":764,"draft":367},"\u002Fblog\u002Fsafest-ai-app-builder","Який білдер застосунків з ШІ найбезпечніший? 30 998 тестів","Який білдер застосунків з ШІ найбезпечніший? Ми просканували 30 998 живих застосунків з Lovable, Base44, Replit, v0 і Bolt. Оцінку вирішує не білдер.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":766,"title":767,"description":768,"published":769,"category":363,"image":770,"draft":367},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Увімкніть Row Level Security на кожній таблиці Supabase і перевірте","Row Level Security у Supabase без політики закриває таблицю повністю. Політика без увімкненого перемикача не робить нічого. Ось SQL, і ось перевірка.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":772,"title":773,"description":774,"published":775,"category":363,"image":776,"draft":367},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": чого не бачить попередження","Supabase позначає \"RLS disabled in public\" як помилку. Про політику читання, яка лишає вашу таблицю так само відкритою, він не каже нічого.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":778,"title":779,"description":780,"published":781,"category":363,"image":782,"draft":367},"\u002Fblog\u002Frotate-supabase-service-role-key","Як замінити злитий ключ service_role у Supabase","Supabase каже спершу закрити витік. Інші посібники кажуть міняти негайно. Що правильно, залежить від того, куди саме потрапив ваш ключ service_role.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":784,"title":785,"description":786,"published":787,"category":363,"image":788,"draft":367},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Сканери безпеки для vibe coding у порівнянні, наш теж","Найкращий сканер безпеки для vibe coding залежить від трьох питань, на які не відповідає жоден перелік функцій. Вісім інструментів і ціни.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":790,"title":791,"description":792,"published":793,"category":363,"image":794,"draft":367},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: п’ять перевірок, які зробите самі","Supabase security checker читає ваш опублікований застосунок, а не налаштування проєкту. Ось п’ять перевірок і як виконати кожну самостійно.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":796,"title":797,"description":798,"published":799,"category":363,"image":800,"draft":367},"\u002Fblog\u002Fvibe-coding-security-scanner","Сканер безпеки для vibe coding: чого не бачить скан URL","Сканер безпеки для vibe coding читає ваш робочий застосунок ззовні. Що це охоплює, чотири речі, яких він не бачить, і як читати результат.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":802,"title":803,"description":804,"published":805,"category":363,"image":806,"draft":367},"\u002Fblog\u002Fmissing-security-headers","Відсутні заголовки безпеки: коли це справді важливо","Відсутні заголовки безпеки трапляються в наших звітах найчастіше. Від чого вони захищають і коли це найменш терміновий рядок вашого звіту.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":808,"title":809,"description":810,"published":811,"category":363,"image":812,"draft":367},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Ваш ключ API OpenAI відкритий у фронтенді. Замініть його.","Ключ API OpenAI, відкритий у фронтенді, не можна прив'язати до домену. Замініть його сьогодні, перенесіть виклик на свій сервер і обмежте витрати.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":214,"title":814,"description":815,"published":816,"category":363,"image":817,"draft":367},"Ключ API у фронтенді: що насправді віддають 30 998 застосунків","Ключ API, відкритий у вашому фронтенді, зазвичай є ключем Google Maps. Ми просканували 30 998 vibe-coded застосунків і порахували, що витікає насправді.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":819,"title":820,"description":821,"published":822,"category":472,"image":823,"draft":367},"\u002Fblog\u002Fsupabase-backup-tools-compared","Інструменти резервного копіювання Supabase, і наш серед них","Чотири види інструментів резервного копіювання Supabase, що копіює кожен і коли безкоштовна GitHub Action виграє в будь-якої оплати, нашої теж.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":825,"title":826,"description":827,"published":828,"category":363,"image":829,"draft":367},"\u002Fblog\u002Freplit-secrets-explained","Як користуватися секретами в Replit і що все одно публікується","Як користуватися секретами в Replit: додати, прочитати і усунути дві причини undefined. А ще ключі, які цей інструмент не здатен зберегти в таємниці.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":831,"title":832,"description":833,"published":834,"category":472,"image":835,"draft":367},"\u002Fblog\u002Fback-up-supabase-free-tier","Резервні копії на безкоштовному тарифі Supabase без терміналу","На безкоштовному тарифі Supabase резервних копій немає: копію робите ви. Як зробити її з панелі та що втрачає шлях через CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":837,"title":838,"description":839,"published":840,"category":363,"image":841,"draft":367},"\u002Fblog\u002Fis-supabase-secure","Чи безпечний Supabase? Так. Ваш проєкт це інше питання","Чи безпечний Supabase? Платформа проходить аудити, шифрує дані й тримає пентести. Їхня документація каже, де це закінчується і починаються ваші налаштування.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":843,"title":844,"description":845,"published":846,"category":363,"image":847,"draft":367},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Де знайти API-ключі Supabase: anon, service_role і URL","URL проєкту, ключ anon і ключ service_role лежать на одній сторінці панелі. Ось де вона, і яке з чотирьох значень має бути у вашому застосунку.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":849,"title":850,"description":851,"published":852,"category":363,"image":853,"draft":367},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy в Supabase. Що далі?","\"New row violates row-level security policy\" означає, що Supabase відмовив у записі. Швидке виправлення знову відкриває таблицю для всіх.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":855,"title":856,"description":857,"published":858,"category":363,"image":859,"draft":367},"\u002Fblog\u002Fcors-wildcard-security-risk","Чи є вайлдкард CORS ризиком для безпеки? Майже ніколи.","Чи є вайлдкард CORS ризиком для безпеки? Зазвичай це типове налаштування вашого білдера, і воно не видає нічого, що ваш сервер і так віддавав кожному.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":861,"title":862,"description":863,"published":864,"category":472,"image":865,"draft":367},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching у Supabase це не бекап. Він іде тільки вперед.","Чому branching у Supabase це не бекап: гілка стартує без ваших даних, а мердж переносить саму лише схему. Для чого він потрібен і що брати замість нього.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":867,"title":868,"description":869,"published":870,"category":472,"image":871,"draft":367},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Як відновити резервну копію Supabase, і що ламається потім","Як відновити резервну копію Supabase з панелі або з файлу дампа, що саме замінює відновлення і чому ваш застосунок може лишитися зламаним після нього.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":873,"title":874,"description":875,"published":876,"category":363,"image":877,"draft":367},"\u002Fblog\u002Fsupabase-storage-bucket-public","Ваш бакет Supabase Storage публічний. Чи це проблема?","Публічний бакет Supabase Storage означає, що той, хто має URL файлу, може його відкрити. Він не означає, що хтось може переглянути список вмісту.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":879,"title":880,"description":881,"published":882,"category":363,"image":883,"draft":367},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Чи є проблемою ключ API Google у вашому браузері?","Ключ API Google у відкритому коді сторінки наш сканер знаходить найчастіше, і зазвичай усе гаразд. Вирішує це одне безкоштовне налаштування.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":885,"title":886,"description":887,"published":888,"category":472,"image":889,"draft":367},"\u002Fblog\u002Fai-agent-deleted-my-database","ШІ-агент видалив мої дані в Supabase. Що можна відновити?","ШІ-агент видалив дані з вашої бази. Те, що ви зможете відновити, вирішилося раніше, а наступні хвилини вирішують, скільки з цього вціліє.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":891,"title":892,"description":893,"published":894,"category":363,"image":895,"draft":367},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Чи може будь-хто прочитати вашу базу Supabase? 3 680 застосунків","Чи може будь-хто прочитати вашу базу даних Supabase без входу? Ми просканували 30 998 живих застосунків, зроблених ШІ-білдерами, і виміряли, як часто так.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":897,"title":898,"description":899,"published":894,"category":363,"image":900,"draft":367},"\u002Fblog\u002Fsource-maps-exposed-in-production","Відкриті source maps: ваш застосунок публікує свій вихідний код","Відкрита source map дає будь-кому прочитати оригінальний код вашого застосунку, разом із коментарями. Перевірка за 30 секунд, і що важить насправді.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":902,"title":903,"description":904,"published":905,"category":363,"image":906,"draft":367},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: це той самий anon key?","Supabase замінив anon і service_role публічними та секретними ключами. Який із них має бути у вашому застосунку, а який не має бути ніколи?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":908,"title":909,"description":910,"published":911,"category":472,"image":912,"draft":367},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Чи робить Supabase резервні копії моєї бази? Залежить від тарифу.","Чи робить Supabase резервні копії вашої бази даних? На платних тарифах щодня, на безкоштовному жодної. Як дізнатися, що у вас насправді є.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":914,"title":915,"description":916,"published":917,"category":363,"image":918,"draft":367},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security увімкнено. Таблиця досі публічна.","Увімкнути Supabase Row Level Security не означає захистити таблицю. Захищають політики, а та, що полагодила застосунок, часто впускає всіх.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":920,"title":921,"description":922,"published":917,"category":472,"image":923,"draft":367},"\u002Fblog\u002Fversion-history-is-not-a-backup","Історія версій не є резервною копією. Вона не поверне таблицю.","Lovable і Bolt ведуть історію версій вашого коду. Ваша база даних працює як окремий сервіс, тож відкат назад не поверне ваші дані.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":925,"title":926,"description":927,"published":928,"category":472,"image":929,"draft":367},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Три способи зробити резервну копію бази Supabase, і чого бракує","Панель, pg_dump і керований сервіс. Що насправді зберігає кожен спосіб, що тихо лишає осторонь і який із них переживе втрату акаунта.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":931,"title":932,"description":933,"published":928,"category":363,"image":934,"draft":367},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Які API-ключі безпечні у браузері, а які ні","Ваш ключ anon у Supabase створений, щоб бути публічним. Ключ service_role для цього не створений, і він ігнорує всі правила, які ви задали. Як їх розрізнити.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1794213654508]