Jak sprawdzić bezpieczeństwo aplikacji z Lovable, Bolt, v0 i Base44, zanim zrobi to ktoś inny

Aplikację z logowaniem, bazą danych, panelem użytkownika i płatnościami można dziś zbudować w weekend, nawet bez doświadczenia z backendem. Lovable, Bolt.new, v0 czy Base44 zamieniają kilka promptów w działający produkt. Generator tworzy jednak przede wszystkim to, o co go poproszono. Nie zabezpieczy tego, o czym autor aplikacji nie pomyślał.

Dlatego najsłabszym miejscem takich projektów rzadko jest wygląd. Częściej jest nim niewidoczna dla użytkownika konfiguracja: kto może czytać i zmieniać dane w bazie, gdzie leżą klucze do usług i kto może założyć konto.

Cztery platformy, podobny model działania

Każda z tych platform oddaje dużą część backendu usłudze zarządzanej (BaaS, czyli „backend jako usługa”):

  • Lovable opiera się na Supabase, bezpośrednio albo przez własną usługę chmurową zbudowaną na tym samym modelu. Aplikacja dostaje w kilka chwil bazę PostgreSQL, logowanie, przechowywanie plików i API.
  • Bolt.new również pozwala podpiąć Supabase. Agent przygotowuje interfejs, bazę i integrację bez pisania klasycznego backendu.
  • v0 od Vercela generuje aplikacje w Next.js, a bazę dołącza się przez ekosystem Vercela, np. Supabase albo Neon.
  • Base44 ma własny, zamknięty backend i nie korzysta z Supabase.

Wspólne jest to, że bezpieczeństwo zależy zarówno od dostawcy, jak i od konfiguracji konkretnego projektu. Tej drugiej części platforma za Ciebie nie sprawdzi.

Dlaczego generatory AI tak chętnie używają Supabase

SDK Supabase pozwala wykonywać wiele operacji na bazie bezpośrednio z przeglądarki. Agent nie musi projektować API ani utrzymywać osobnego serwera. Pisze kilka wywołań i aplikacja działa.

W jednym projekcie są baza danych, logowanie, pliki, aktualizacje na żywo i funkcje serwerowe (Edge Functions). Modele AI dobrze znają ten zestaw, bo połączenie Next.js i Supabase od lat pojawia się w dokumentacji, poradnikach i otwartym kodzie. Do tego dochodzi darmowy próg i brak serwerów do utrzymania.

Ta prostota ma drugą stronę: skoro przeglądarka rozmawia bezpośrednio z bazą, to reguły w samej bazie decydują, kto zobaczy jakie dane.

Klucz publiczny to nie sekret. Klucz administracyjny – tak

Adres projektu Supabase i klucz anon (w nowszych projektach: publishable) widoczne w kodzie strony z założenia nie są sekretami. Ich obecność w JavaScripcie nie oznacza podatności. Problem zaczyna się wtedy, gdy baza ufa temu kluczowi bardziej, niż powinna.

Główną linią obrony jest Row Level Security (RLS): polityki określające, które wiersze tabeli może odczytać lub zmienić konkretny użytkownik.

Zupełnie inaczej trzeba traktować klucz service_role (w nowszych projektach: secret) i inne klucze uprzywilejowane. Omijają one RLS i wykonują operacje administracyjne. Jeśli taki klucz trafi do kodu wysyłanego do przeglądarki – na przykład przez zmienną z przedrostkiem VITE_ albo NEXT_PUBLIC_ – każdy może zrobić z bazą wszystko.

Najczęstsze błędy w aplikacjach tworzonych przez AI

RLS wyłączone albo tylko pozornie poprawne

Najprostszy błąd to tabela dostępna przez API bez polityk RLS. Równie groźne są reguły w rodzaju USING (true) albo zgoda dla każdego zalogowanego użytkownika na dostęp do wszystkich wierszy. Aplikacja wygląda wtedy na bezpieczną, bo wymaga logowania, ale założenie zwykłego konta wystarcza, żeby zobaczyć cudze dane.

Łatwo też zabezpieczyć pierwsze tabele, a potem dodać kolejną z nowego promptu i zapomnieć o politykach.

To nie jest problem teoretyczny. W przypadku opisanym jako CVE-2025-48757 badacz sprawdził aplikacje z publicznej galerii Lovable i znalazł ponad 170 projektów, w których tabele dało się czytać lub zmieniać samym kluczem publicznym. Wśród odsłoniętych danych były adresy e-mail i numery telefonów użytkowników, a w części aplikacji także klucze API i dane płatności. Wygenerowanie działającej tabeli nie oznacza wygenerowania poprawnych uprawnień.

Role, funkcje i endpointy omijające zabezpieczenia

Rola użytkownika (np. „admin”) nie powinna być zapisana w polu, które użytkownik może sam zmienić. Funkcje SQL z SECURITY DEFINER, wywołania RPC i źle skonfigurowane widoki mogą działać z pominięciem RLS. Edge Function, która przyjmuje identyfikator dokumentu, ale nie sprawdza, czy wywołujący jest jego właścicielem, pozwala pobrać cudzy dokument po samej zmianie numeru w żądaniu (w żargonie: IDOR/BOLA).

Sekrety w kodzie strony

Klucz API OpenAI albo prywatny klucz Stripe znaleziony w kodzie frontendu zamienia drobną pomyłkę w konkretny rachunek albo dostęp do płatności.

Pliki, rejestracja kont i kopie zapasowe

Sprawdzenie nie może kończyć się na tabelach. Publiczny bucket z fakturami czy dokumentami jest równie groźny jak źle zabezpieczona baza. Trzeba przejrzeć polityki przechowywania plików (storage.objects), ustawienia rejestracji, potwierdzanie adresów e-mail i limity żądań. W aplikacji dla pracowników firmy możliwość samodzielnej rejestracji dowolnej osoby powinna od razu budzić podejrzenia.

Do tego dochodzą kopie zapasowe, możliwość odtworzenia danych, logi i region przechowywania danych, a przy danych osobowych – RODO. Bez logów po incydencie wiadomo, że drzwi były otwarte, ale nie wiadomo, czy ktoś przez nie wszedł.

Jak sprawdzić aplikację przed wdrożeniem

Z zewnątrz, jak obcy użytkownik

Zaczynam od tego, co widzi każdy odwiedzający: publiczne pliki aplikacji, konfiguracja klienta Supabase i sposób logowania. Potem sprawdzam, czy da się odczytać lub zmienić dane anonimowo i po zalogowaniu na świeżo założone konto, czy pliki w Storage są dostępne bez uprawnień i czy kod strony nie zawiera sekretów.

Takie testy wolno wykonywać wyłącznie na własnych aplikacjach albo za wyraźną, najlepiej pisemną zgodą właściciela. Nieuprawniony dostęp do cudzych danych może być przestępstwem, w Polsce m.in. z art. 267 Kodeksu karnego.

Od środka, z dostępem do projektu

Z dostępem do projektu Supabase można sprawdzić, które tabele mają włączone RLS (pg_tables.rowsecurity) i jakie mają polityki (pg_policies), uruchomić Security Advisor i przejrzeć wynik supabase db lint. Następnie trzeba przejrzeć migracje, funkcje SQL, widoki i Edge Functions oraz ustalić, gdzie używany jest klucz administracyjny.

Na koniec porównuję uprawnienia z tym, jak działa firma: użytkownik ma mieć dostęp nie do „tabeli zamówień”, tylko do swoich zamówień. Supabase publikuje własne checklisty bezpieczeństwa i wskazówki do polityk RLS – to dobry punkt wyjścia.

Między „build successful” a produkcją potrzebny jest przegląd

Vibe coding sam w sobie nie jest problemem. Problem pojawia się wtedy, gdy między komunikatem „build successful” a wpuszczeniem użytkowników nie ma etapu przeglądu bezpieczeństwa.

W praktyce wystarczą trzy nawyki: w promptach wymagaj polityk RLS dla każdej nowej tabeli, przed każdym wdrożeniem uruchamiaj Security Advisor, a przed pierwszymi prawdziwymi użytkownikami zrób osobny przegląd uprawnień – samodzielnie albo z kimś, kto zna Supabase.

Pytania przed pierwszym użytkownikiem

Czy klucz anon Supabase widoczny w JavaScripcie oznacza wyciek?

Nie. To klucz publiczny z założenia. O bezpieczeństwie decydują polityki dostępu w bazie.

Czy samo włączenie RLS wystarcza?

Nie. Błędna polityka, np. USING (true), może być równie groźna jak jej brak.

Czy klucz service_role może trafić do frontendu?

Nie. To sekret z pełnymi uprawnieniami; powinien działać wyłącznie na serwerze.

Co sprawdzić po dodaniu nowej tabeli przez AI?

Czy ma włączone RLS, jakie ma polityki dla odczytu, dodawania, zmiany i usuwania (SELECT, INSERT, UPDATE, DELETE), jak łączy się z użytkownikami i czy nie jest dostępna szerzej, niż zakładano.

Kiedy robić przegląd bezpieczeństwa?

Najpóźniej przed uruchomieniem produkcji i ponownie po większych zmianach w bazie, logowaniu lub uprawnieniach.

Powiązana stronaAplikacje internetowe

Więcej z bloga

Opisz proces, który chcesz uporządkować

Napisz, jak dziś wygląda praca i gdzie pojawiają się problemy. Gotowa specyfikacja nie jest potrzebna.