Īsumā
Lovable lietotne ir tik droša, cik droša ir tās Supabase datubāze, un “RLS ir ieslēgts” pierāda ļoti maz. Testējiet ar diviem lietotājiem divos uzņēmumos, turiet lomas ārpus lietotāja metadatiem, turiet slepeno atslēgu ārpus pārlūka un atsevišķi pārbaudiet piešķirtās tiesības, skatus, storage, funkcijas un ātruma ierobežojumus, jo katrs no tiem apiet jūsu politikas savā veidā. Zemāk ir saraksts, ko palaižu, uzvedne, ko varat ielīmēt Lovable vai Claude, un astoņas pārbaudes, ko pievienoju pēc tam, kad klienta Lovable lietotne parādīja, ko pirmās divpadsmit izlaiž.
Es esmu Denys, full-stack un AI inženieris. Šomēnes es labojau klienta lietotni, kas izveidota ar Lovable. Viss darbojās uz Supabase, kā parasti, un drošības labojumu bija tik daudz, ka šķita, ka lietotne no tiem sastāv. Šo sarakstu es tagad izeju katrā Lovable vai Supabase projektā, pirms saku, ka klientu dati ir aizsargāti.
Vai Lovable ir drošs? Līdz šim zināmās drošības problēmas
Platforma izveido un mitina jūsu lietotni, taču lietotnes drošība lielākoties ir atkarīga no tās aizmugurē esošās Supabase datubāzes, jo lietotne šo datubāzi lasa un raksta tieši no pārlūka. Publiski zināmie gadījumi parāda abu veidu problēmas:
| Kad | Kas notika | Avots |
|---|---|---|
| 2025. gada marts | CVE-2025-48757: 1645 Lovable demonstrācijas lietotņu skenēšana atrada 303 endpoint 170 no tām, kas atdeva datus ikvienam ar publisko atslēgu, jo RLS trūka vai bija pārāk vaļīgs | Matt Palmer atklājums, 2025. gada maijs |
| 2026. gada februāris | Viena Lovable mitināta lietotne atklāja 18 697 lietotāju ierakstus; piekļuves pārbaude tās funkcijās ielaida anonīmus apmeklētājus un bloķēja pieteikušos lietotājus. Lovable norādīja, ka daļu koda Lovable nav ģenerējis | The Register, 2026. gada 27. februāris |
| No 2026. gada 3. februāra līdz 20. aprīlim | Platformas regresija ļāva citiem Lovable lietotājiem lasīt publisko projektu tērzēšanas vēsturi un pirmkodu | Lovable incidenta ieraksts, 2026. gada 22. aprīlis |
Pirmie divi ir lietotnes līmeņa robi, tādi, kādus noķer zemāk esošās pārbaudes. Trešā bija paša Lovable kļūda, un Lovable to izlaboja; jūsu daļa ir turēt atslēgas ārpus tērzēšanas un koda (3. pārbaude) un nomainīt visas, kas tur bija. Lovable pirms publicēšanas palaiž drošības skenēšanu, taču rīkoties pēc tās rezultātiem ir jūsu ziņā, un brīdī, kad CVE tika publicēts, šī skenēšana pārbaudīja, vai politika pastāv, nevis vai tā ir pareiza. Tāpēc jautājums “vai Lovable ir drošs” beidzas ar to, vai jūsu datubāze iztur zemāk esošās pārbaudes.
Kāpēc ar “RLS ir ieslēgts” Lovable lietotnē nepietiek?
Lovable lietotne runā ar datubāzi tieši no pārlūka. Starp tiem nav jūsu pašu backend: lapa izsauc Supabase Data API ar publisku atslēgu, un Postgres izlemj, ko atdot (kuras shēmas šis API sniedz, ir atsevišķs iestatījums, ko aplūko piezīme Supabase exposed schemas). Tāpēc katram noteikumam, kas sargā klientu datus, jādzīvo datubāzē, un datubāzei ir vairākas durvis.
Row level security ir viena no tām. Piešķirtās tiesības (grants) nosaka, vai loma vispār drīkst pieskarties tabulai, politikas nosaka, kuras rindas, un trīs lietas politikas apiet pavisam: slepenā atslēga, skati, izveidoti bez security_invoker, un SECURITY DEFINER funkcijas. Tas nav hipotētiski. Paša Lovable drošības ceļvedis liek pārskatīt RLS politikas, ko tas iestata, un augstāk minētais CVE-2025-48757 ir tas, kas notiek, kad neviens to nedara.
Uzvedne: ielīmējiet to Lovable vai Claude
Varat ielīmēt kā ir. Pēc tam rezultātu pārbaudiet paši: AI mīl teikt “gatavs”, kad tā nav, un uzvedne, kas liek kļūdai pazust, var to panākt, paplašinot piekļuvi.
Pārbaudi šo projektu drošības ziņā, izlabo atrasto un pastāsti, ko mainīji:
1. Testē ar diviem lietotājiem divos uzņēmumos. A lietotājs mēģina lasīt, rediģēt un dzēst B ierakstus pēc id, caur API, meklēšanu un eksportiem. Visiem mēģinājumiem jāizgāžas.
2. RLS katrā tabulā, politikas pārbauda rindas īpašnieku vai uzņēmumu. "Pieteicies" nepietiek.
3. Service role key nekad nav frontendā. Edge function, kas to izmanto, pati pārbauda lietotāju un filtrē pēc uzņēmuma, jo atslēga apiet RLS.
4. Lomas, plānu, uzņēmuma id nekad neņem no user metadata, lietotāji to var rediģēt. Glabā tabulā, ko raksta tikai serveris.
5. Ja pieprasījums sūta divus id (projekts + uzdevums), pārbaudi, vai uzdevums pieder šim projektam.
6. Atsauc visas tabulu privilēģijas no anon un authenticated, atdod atpakaļ tikai to, ko prasa politikas. RLS neaptur TRUNCATE. Katra migrācija, kas izveido tabulu, ietver tās GRANT: no 2026. gada 30. oktobra Supabase jaunām tabulām tiesības vairs nepiešķir automātiski, un lietotne saņem kļūdu 42501.
7. Visi skati ar security_invoker = true, citādi tie apiet RLS.
8. Storage buckets: lietotāji lasa un raksta tikai savus failus, privātiem datiem nav publisku buckets.
9. SECURITY DEFINER funkcijas: NULL nozīmē aizliegt, nevis atļaut.
10. Ātruma ierobežojumi pieteikšanās, reģistrācijas, atiestatīšanas un OTP, glabāti DB, nevis atmiņā.
11. Validē visu ievadi serverī.
12. Palaid Supabase security advisor, izlabo katru brīdinājumu.
12 pārbaudes un kā pierādīt katru
1. Divi lietotāji divos uzņēmumos
Izveidojiet lietotāju A uzņēmumā 1 un lietotāju B uzņēmumā 2, katram dažus ierakstus. Piesakieties kā A un mēģiniet lasīt, rediģēt un dzēst B ierakstus pēc id, caur API, caur meklēšanu un caur katru eksportu. Katram mēģinājumam jāatgriež nekas vai kļūda. Šis ir vienīgais tests, kas noķer lielāko daļu no sekojošā, jo tas pārbauda to, ko dara uzbrucējs, nevis to, ko uzrakstījāt jūs.
Pievienojiet trešo lietotāju, kas pieder abiem uzņēmumiem. Politika formā “izsaucējs ir rindas uzņēmuma dalībnieks” ļauj šim lietotājam lasīt 2. uzņēmuma rindas, strādājot 1. uzņēmumā. Citā Supabase lietotnē mana zonde ar tādu lietotāju atgrieza otra uzņēmuma dokumentu, līdz vaicājums tika papildināts ar filtru pēc pieprasījuma uzņēmuma. Šo aprakstīju kā lietotājs divās org., ko RLS neizolēja.
2. RLS katrā tabulā, piesaistīts īpašniekam vai uzņēmumam
auth.uid() is not null nozīmē “jebkurš pieteicies lietotājs”, kas publiskā reģistrācijas lapā nozīmē jebkuru. Katra politika salīdzina rindas īpašnieku vai uzņēmumu ar izsaucēju. Uzskaitiet tabulas, kurām RLS vēl ir izslēgts:
select c.relname
from pg_class c join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public' and c.relkind in ('r', 'p') and not c.relrowsecurity;
3. Slepenā atslēga nekad nav frontendā
Service role key un jaunākā sb_secret_ atslēga apiet katru politiku. Meklējiet abas sagatavotajā JavaScript un nomainiet katru atslēgu, kas jebkad nonākusi pārlūkā. Edge function, kas to izmanto, pati pārbauda, kas ir lietotājs, un pati filtrē pēc uzņēmuma, jo ar šo atslēgu to nedarīs nekas cits.
4. Lomas, plāns un uzņēmuma id nekad no lietotāja metadatiem
raw_user_meta_data ir viss, ko klients nosūtīja uz signUp, un lietotāji to vēlāk var mainīt. Citā lietotnē jauna lietotāja trigeris no turienes nolasīja ielūgto lomu, tāpēc ikviens, kas reģistrējās, varēja nodot īpašnieka lomu un kļūt par Owner. Glabājiet lomas, plānus un uzņēmumu id tabulā, ko raksta tikai serveris, vai app_metadata. Pilns stāsts: loma, kas ņemta no reģistrācijas metadatiem.
5. Divi id vienā pieprasījumā: pārbaudiet, vai tie pieder kopā
Ja pieprasījumā ir projekta id un uzdevuma id, ar projekta autorizēšanu nepietiek. Lietotājs ar tiesībām projektā A nosūta A un sadaļas id no projekta B, un rinda nonāk B. RLS to nenoķer, jo ievietošana atzīmē uzbrucēja paša projekta id, tieši to politika arī pārbauda. Pirms rakstāt, pārbaudiet, ka pakārtotais ieraksts pieder vecākam.
6. Piešķirtās tiesības: atsaukt, tad atdot tikai vajadzīgo
Piešķirtās tiesības (grants) un politikas ir divi atsevišķi slāņi. Politiku pievienošana tiesības neatņem, tāpēc Supabase RLS ceļvedis liek tās atsaukt un atdot skaidri. Citā projektā supabase/postgres 17.6.1 attēls bija devis anon un authenticated TRUNCATE, REFERENCES, TRIGGER un MAINTAIN uz katras tabulas public, un neviena politika uz TRUNCATE neattiecas. Data API nav TRUNCATE endpoint, tāpēc tā nav dzēšana ar vienu pieprasījumu, taču nevienai klienta lomai tas nav vajadzīgs, un jebkura funkcija, kas izpilda SQL ar šo lomu, to manto.
revoke all on public.orders from anon, authenticated;
grant select, insert, update on public.orders to authenticated;
select grantee, table_name, privilege_type
from information_schema.role_table_grants
where table_schema = 'public' and grantee in ('anon', 'authenticated')
order by table_name;
Viens datums šo pārbaudi maina. Supabase pārtrauc automātiski piešķirt tiesības jaunām tabulām: jauniem projektiem kopš 2026. gada 30. maija un visiem esošajiem projektiem no 2026. gada 30. oktobra, arī tiem, ko izveidoja Lovable. Pēc tam tabula, ko Lovable vai migrācija izveido bez skaidra GRANT, lietotnei ir neredzama: pieprasījums beidzas ar kļūdu 42501, un funkcija, kas izmanto tabulu, salūst. Tāpēc katra migrācija, kas izveido tabulu, tagad nes savas tiesības blakus enable row level security un politikām.
Divas lietas paliek nemainīgas. Esošās tabulas saglabā tiesības, kas tām ir, tāpēc nevajadzīgo atsaukšana joprojām ir jūsu darbs. Un izmaiņa atņem tikai select, insert, update un delete: Lovable projektā ar jaunajiem noklusējumiem jaunas tabulas joprojām nāca ar TRUNCATE, REFERENCES, TRIGGER un MAINTAIN priekš anon un authenticated. Vispirms atsaukt visu, tad piešķirt, joprojām ir drošā secība.
7. Katrs skats ar security_invoker = true
Skats darbojas ar sava īpašnieka tiesībām, un Supabase īpašnieks parasti ir postgres, tāpēc skats virs aizsargātas tabulas atdod katru rindu, ko politikas liedz. Postgres 15 un jaunākā versijā:
alter view public.customer_summary set (security_invoker = true);
8. Storage: tikai savi faili, nekādu publisko bucket privātiem datiem
Publisks bucket atdod jebkuru failu ikvienam, kam ir URL. Privātie faili jāliek privātā bucket ar politikām uz storage.objects, kas pārbauda īpašnieku vai uzņēmumu, parasti pēc ceļa pirmās mapes. Pēc projekta pārcelšanas saskaitiet spēkā esošās storage politikas: vienā lietotnē pēc pārcelšanas neizdevās katra augšupielāde, jo politiku migrācija nekad nepalaidās un tabulai bija ieslēgts RLS ar nulli politiku.
9. SECURITY DEFINER funkcijas: NULL nozīmē aizliegt
PL/pgSQL if not (has_permission or assignee_id = auth.uid()) neizmet kļūdu, ja assignee_id ir null: viss nosacījums ir null, un if to izlaiž. Tā pati izteiksme politikā ir droša, jo politika null uzskata par aizliegumu. Vienā lietotnē tas ļāva lomai ar izslēgtām visām atļaujām darboties ar visiem 3683 uzdevumiem, jo nevienam nebija atbildīgā. Ietiniet nosacījumu coalesce(…, false). Sīkāk: NULL PL/pgSQL IF NOT izlaida pārbaudi 3683 uzdevumiem.
10. Ātruma ierobežojumi, kas glabājas datubāzē
Ierobežojiet pieteikšanos, reģistrāciju, paroles atiestatīšanu un OTP, un skaitītāju glabājiet Postgres. Lovable lietotnē ierobežojumi dzīvoja mainīgajā edge function iekšienē. Mitināto projektu pārbaudīju 2026. gada 17. oktobrī: katrs pieprasījums darbojās jaunā isolate, tāpēc skaitītājs atmiņā vienmēr bija 1 un ierobežojums nekad nevarēja iedarboties. Lokālais supabase functions serve isolate izmanto atkārtoti, tāpēc tas pats kods izturēja visus lokālos testus.
Atslēga ir tikpat svarīga kā glabātuve. Mitinātajā platformā pēdējais X-Forwarded-For lēciens ir pašas Supabase starpniekserveris, tāpēc atslēga uz tā ievieto visus izsaucējus vienā grozā, bet x-client-ip iestata klients. Manā zondē īsto klientu nesa cf-connecting-ip. Labojums bija SECURITY DEFINER funkcija claim_rate_limit(bucket, key, max, window), ko var izpildīt tikai service role, serializēta ar advisory lock, kas glabā IP vai lietotāja id jaucējkodu, nevis neapstrādātu vērtību.
11. Validējiet visu ievadi serverī
Lai ko pārbauda forma, API pieņem visu, ko sūta klients. Garumus, formātus, enum un piederību pārbauda datubāzē (ierobežojumi, trigeri) vai edge function, nekad tikai React.
12. Supabase Security Advisor, katrs brīdinājums
Atveriet Advisors, tad Security Advisor, un izlabojiet katru atradumu. Tas norāda tabulas ar izslēgtu RLS, skatus, kas apiet RLS, politikas, kas lasa lietotāja metadatus, pieļāvīgas using (true) politikas un funkcijas ar mainīgu search_path. Tas neredz 1., 5., 9. un 10. pārbaudi, jo tās ir par loģiku, nevis konfigurāciju.
Ko Lovable lietotne iemācīja, ko šīs 12 izlaiž?
Šie atklājumi nāca no klienta lietotnes un tās pārskatiem. Neviens no tiem neparādās skenerī.
- Lauki, ko klients nedrīkst iestatīt. Klients pats nosūtīja
status: 'approved', kas apgāja moderāciju. UPDATE politika, kuraswith checkir brīvāks parusing, ļauj arī pārvietot rindu pie cita īpašnieka. Politika nevar aprēķināt vērtību, tāpēcBEFORE INSERT OR UPDATEtrigeris no servera paša datiem no jauna atvasinastatus, lomu, cenu un uzņēmumu un ignorē to, ko sūtīja klients. - Katrs rakstīšanas ceļš, ne tikai galvenā ievietošana. Pēc galvenās ievietošanas labošanas tas pats apiešanas ceļš bija pielikumos, komentāros, dzēstas vienības atjaunošanā un skaitītājos. Pirms labojat pirmo, uzskaitiet katru aizsargātās kolonnas rakstītāju.
- Atļauju saraksti, nevis aizliegumu saraksti. Viltotie ieraksti prasīja piecas pārskatu kārtas, jo katrs labojums bloķēja vienu kombināciju un atstāja kaimiņu atvērtu. Trigeris, kas atļauj tikai uzskaitītās tipa un statusa kombinācijas, aizvēra visu klasi uzreiz.
- Funkcijas arī ir API. Katru funkciju shēmā
publiccaur/rpcvar izsaukt jebkura loma ar EXECUTE, un RLS uz funkcijām neattiecas. KatraiSECURITY DEFINERfunkcijai iestatietset search_path = '', atsauciet EXECUTE nopublic,anonunauthenticatedun piešķiriet to tikai lomai, kurai tas vajadzīgs. - EXECUTE atsaukšana var salauzt publiskās lapas. Postgres pārbauda EXECUTE katrai funkcijai, ko izmanto katra politika, kas attiecas uz lomu, pat zarā, kas nekad neizpildītos. Kad
anonzaudēja EXECUTE uzis_admin(), katrs anonīmais lasījums izgāzās ar 42501. Administratoru politikas liekto authenticated, bet publiskajiem lasījumiem dod savu politiku bez administratora zara. - Reģistrācija ar ieslēgtu e-pasta apstiprināšanu. Ar ieslēgtu apstiprināšanu
signUpneatgriež sesiju, tāpēc jebkurš profila ieraksts uzreiz pēc tā darbojas kāanonun klusi neieraksta neko. Lovable projektos bieži ir ieslēgta automātiskā apstiprināšana, kas kļūdu paslēpj. Nododiet laukus caursignUp({ options: { data } }), ļaujiet jauna lietotāja trigerim tos validēt un rakstīt, un uzskatiet šos metadatus par neuzticamiem (4. pārbaude). - Testi, kas iziet nepareizā iemesla dēļ. Lokālajam stekam un mitinātajam projektam bija atšķirīgas noklusējuma privilēģijas, tāpēc “anon nevar ievietot” lokāli izgāja, jo trūka tiesību, nevis tāpēc, ka darbojās RLS. Negatīvam testam ir jēga tikai tad, ja pozitīvā tiesība pastāv. Salīdziniet
pg_default_acllokāli un produkcijā. - Dzīvā datubāze, nevis migrāciju faili. Pēc migrācijas vai projekta pārcelšanas salīdziniet to, kas patiešām darbojas:
pg_policies,pg_get_functiondefkatram aizsargam un iepriekš minētās tiesības. Citā lietotnē jauna migrācija nokopēja vecu funkcijas pamatteksta versiju un klusi atcēla vēlāku labojumu.
Vai Lovable lietotne atbilst GDPR?
Lovable nepadara lietotni atbilstošu vai neatbilstošu; to izšķir tas, ko lietotne dara ar personas datiem, un drošības pārskats uz to neatbild. Šīs ir sešas nepilnības, ko pārbaudu Lovable Cloud lietotnē, katra ar labojumu:
- Uzskaitiet visus apstrādātājus. Lovable Cloud darbina datubāzi, autentifikāciju, krātuvi un funkcijas uz Supabase, Lovable hostē vietni un var sūtīt pieteikšanās e-pastus, un Lovable AI Gateway nodod tekstu modeļa nodrošinātājam. Pievienojiet katru e-pasta, AI vai scraping pakalpojumu, ko izsauc jūsu funkcijas. Katram, kas saņem personas datus, vajadzīgs datu apstrādes līgums (DPA), un tam, kas atrodas ārpus ES, vēl arī datu nodošanas mehānisms. Hostinga reģions kodā neparādās, tāpēc pajautājiet to.
- Izdzēsiet lietotāju, kuram ir saturs. Ārējās atslēgas no tā, ko lietotājs uzrakstījis, var bloķēt dzēšanu, un tad dzēšanas pieprasījumu nevar izpildīt. Iestatiet šīm atslēgām cascade vai set null, pievienojiet dzēšanas trigeri, kas noņem arī lietotāja e-pasta žurnālus un pieteikšanās tokenus, un paturiet datubāzes testu, kas izdzēš šādu lietotāju.
- Nosakiet glabāšanas termiņu. E-pasta žurnāli, skatījumu uzskaite, neizdevušos e-pastu rindas un mīksti dzēstas rindas bieži glabā personas datus bez beigu datuma. Ieplānots darbs, kas pēc noteikta termiņa galīgi izdzēš mīksti dzēstās rindas un noņem to failus, aizver lielāko daļu.
- E-pastu izsekošana tikai ar piekrišanu. Atvēršanas un klikšķu reģistrēšana katram saņēmējam pēc ePrivacy noteikumiem prasa piekrišanu: piekrišanas karogs, pēc noklusējuma izslēgts, ar laikspiedolu, ko iestata serveris, nevis klients.
- Turiet adreses ārpus funkciju žurnāliem. Edge function žurnāli netiek tīrīti, tāpēc
console.logar saņēmēja adresi to tur atstāj. Reģistrējiet ID un skaitus. - Ieslēdziet e-pasta apstiprināšanu. Ar automātisko apstiprināšanu ikviens var reģistrēties ar adresi, kas viņam nepieder, un ienest lietotnē īsta cilvēka adresi. Augstāk esošā saraksta 6. punkts aptver reģistrācijas pusi.
Kā pārbaudīt savu lietotni: meklējiet funkcijās API atslēgas, lai uzskaitītu pakalpojumus, izdzēsiet testa lietotāju ar saturu, meklējiet @ funkciju žurnālos un palūdziet katram nodrošinātājam datu apstrādes līgumu. Tas nav juridisks padoms.
Kā neļaut tam atgriezties?
Katra pārbaude augstāk ir vaicājums vai tests, tāpēc glabājiet tos repozitorijā un palaidiet pirms katras izvietošanas. Supabase pgTAP testi sedz tiesības, politikas un funkcijas; divu uzņēmumu tests jāliek blakus. Ja jūsu lietotnei ir lomas un atļauju ekrāns, arī ar testu katrai politikai nepietiek: katru atļauju rūtiņu es pierādu pret produkcijas kopiju, kā aprakstīts rakstā kā testēt Supabase RLS, kur 30 no 87 rūtiņām neko nedarīja. Bezmaksas Supabase drošības pārbaude palaiž 46 OWASP Top 10:2025 noteikumus pret projekta lomām, tiesībām, politikām un autentifikācijas iestatījumiem, tāpēc izmantojiet to pirmajam piegājienam; divu uzņēmumu tests un viss, kas attiecas uz jūsu saskarni, paliek manuāls.
Ko šis saraksts neaptver: maksājumus un webhooks, noslēpumus jūsu Git vēsturē, drošības headers uz hosta, rezerves kopijas. Tie ir svarīgi, bet tas ir cits kontrolsaraksts.
Ja esat mantojis Lovable vai Supabase lietotni un neesat pārliecināti, kuras no šīm pārbaudēm tā iztur, ar šo auditu sākas projekta glābšana. Revīzijas uzņēmuma darba laika uzskaites gadījums rāda, kā lomu pārbaudes izskatās produkcijas lietotnē.
Atradāt robu, ko šis saraksts izlaiž?
Labprāt to uzzinātu. Labprāt salīdzināšu pieredzi par Lovable un Supabase lietotņu drošināšanu.
Sazināties