Bezpieczeństwo według stacku

Bezpieczeństwo aplikacji tworzonych przez AI

Aplikacje z vibe codingu powstają w kilka godzin, ale podstawy bezpieczeństwa —ujawnione klucze, brak reguł bazy danych, otwarty CORS, brakujące nagłówki— gubią się po drodze. Ten poradnik wyjaśnia bez żargonu luki, które naprawdę uderzają w aplikacje tworzone przez AI, dlaczego powtarzają się raz za razem, jak sprawdzić je samodzielnie w dziesięć minut albo skanerem w 30 sekund, i czego pilnować po starcie.

Co oznacza „bezpieczeństwo w vibe codingu"

Narzędzia AI (Lovable, Bolt, v0, Cursor, Replit, Windsurf) generują aplikacje o bardzo konkretnej architekturze: przeglądarka rozmawia bezpośrednio z bazą danych (Supabase, Firebase) i z usługami zewnętrznymi (Stripe, OpenAI, Resend). Po drodze prawie nie ma własnego serwera. To wszystko przyspiesza, ale przenosi bezpieczeństwo z Twojego kodu do konfiguracji: chronią Cię reguły bazy danych, nagłówki HTTP, polityka CORS i to, gdzie trzymasz klucze, a nie to, jak czysty jest kod interfejsu.

Te elementy nie są domyślnie dobrze ustawione, a AI rzadko je konfiguruje, jeśli o to nie poprosisz. Jej celem jest, żeby aplikacja działała na demo, a tabela bez ograniczeń albo klucz wklejony do frontendu „działają" bez zarzutu. Efekt: aplikacje, które wyglądają nienagannie, a ujawniają dane lub klucze każdemu, kto wie, gdzie patrzeć. Nie trzeba być hakerem, wystarczy otworzyć narzędzia deweloperskie przeglądarki.

Dlatego „bezpieczeństwo w vibe codingu" nie oznacza nauki kryptografii ani zamawiania audytu. Oznacza znajomość pół tuzina luk, które powtarzają się w niemal każdej aplikacji tworzonej przez AI, umiejętność sprawdzenia ich z zewnątrz i poproszenie tej samej AI o naprawę z precyzyjnymi instrukcjami.

Dlaczego aplikacje tworzone przez AI zawodzą w tych samych miejscach

Jest pewien wzorzec. AI optymalizuje pod to, żeby kod się skompilował, a ekran pokazał dane, nie pod to, żeby obcy ich nie zobaczył. Kiedy zapytanie pada na uprawnieniach, najkrótsze rozwiązanie to usunąć przeszkadzające uprawnienie: wyłączyć Row Level Security, dodać regułę pozwalającą na wszystko albo użyć klucza administratora. A AI wybiera najkrótsze rozwiązanie.

Drugi powód: kopiuje szablony. Zmienne z prefiksem NEXT_PUBLIC_, VITE_ czy NUXT_PUBLIC_ są z założenia wysyłane do przeglądarki, a wiele przykładów w internecie umieszcza tam klucze, które nigdy nie powinny opuścić serwera. Reguły Firebase w trybie testowym pozwalają każdemu czytać i pisać przez 30 dni, a aplikacje startują z tym trybem włączonym. Nagłówki bezpieczeństwa nie pojawiają się prawie w żadnym tutorialu, więc nie pojawiają się też w aplikacji.

Trzeci: nikt nie rysuje modelu zagrożeń. Kto buduje z AI, myśli o użytkowniku, którego chce, a nie o odwiedzającym, który otwiera zakładkę Network, kopiuje URL API i usuwa filtr. Ten poradnik polega na postawieniu się na dziesięć minut w roli tego odwiedzającego.

Siedem luk, które najczęściej uderzają w aplikacje tworzone przez AI

Klucze API w przeglądarce. Gdy „podłączasz" usługę, klucz ląduje w JavaScripcie klienta, gdzie na zawsze jest publiczny: każdy może go odczytać w źródle strony i użyć na Twój koszt (rachunki OpenAI, e-maile wysyłane z Twojej domeny, dostęp do Twoich danych). Jedyne klucze, które mogą trafić do klienta, to te do tego zaprojektowane, jak klucz anon lub publishable Supabase, klucz publiczny Stripe czy konfiguracja Firebase, i tylko jeśli reguły za nimi są poprawne.

Brak lub słabe reguły bazy danych. Bez Row Level Security włączonego na każdej tabeli Supabase, albo z polityką pozwalającą na wszystko, każdy czyta i zapisuje Twoje dane bez logowania, przez to samo API, którego używa Twoja aplikacja. W Firebase to samo robią reguły w trybie testowym albo z allow read, write: if true. To najpoważniejsza i najczęstsza luka, i to ona była źródłem podatności CVE-2025-48757, która ujawniła dane użytkowników w aplikacjach zbudowanych w Lovable.

Liberalny CORS. API, które odpowiada nagłówkiem Access-Control-Allow-Origin odbijającym dowolne źródło i dodatkowo pozwala na poświadczenia, umożliwia złośliwej stronie wysyłanie żądań w imieniu Twoich użytkowników i czytanie odpowiedzi. Gwiazdka w publicznym API bez ciasteczek jest akceptowalna; odbijanie źródła z poświadczeniami, nigdy.

Brakujące nagłówki bezpieczeństwa. Bez Content-Security-Policy, Strict-Transport-Security, X-Frame-Options (lub frame-ancestors), X-Content-Type-Options, Referrer-Policy i Permissions-Policy Twoja aplikacja jest otwarta na clickjacking, wstrzykiwanie skryptów, downgrade do HTTP i wycieki wewnętrznych URL-i. Konfiguruje się je na serwerze lub u hostingu (Vercel, Netlify, Cloudflare) w dziesięć linii.

Dostępne wrażliwe pliki. Opublikowany przez pomyłkę .env, wystawiony katalog .git, source mapy pozwalające odtworzyć cały kod źródłowy, kopie zapasowe bazy danych albo panele administracyjne bez uwierzytelniania. Łatwo je znaleźć, bo atakujący szukają ich automatycznie na każdej nowej domenie.

Źle skonfigurowane sesje i ciasteczka. Ciasteczka sesyjne bez atrybutów Secure, HttpOnly i SameSite, tokeny trzymane w localStorage w zasięgu dowolnego skryptu albo sesje, które nigdy nie wygasają. Mały XSS zamienia się w przejęcie konta, gdy ciasteczko da się odczytać z JavaScriptu.

Endpointy ufające klientowi. Route'y API, które przyjmują identyfikator użytkownika, cenę albo rolę z ciała żądania bez sprawdzenia na serwerze. Jeśli interfejs ukrywa przycisk administratora, ale route nadal odpowiada każdemu, ten przycisk niczego nie chroni.

Co sprawdzić w zależności od stacku

Lovable, Bolt lub v0 z Supabase. Sprawdź, czy wszystkie tabele mają włączone RLS i polityki dla każdej operacji (select, insert, update, delete) oparte na auth.uid(); czy klucz service_role nie siedzi w żadnej publicznej zmiennej; czy prywatne buckety Storage mają polityki; i czy widoki oraz funkcje RPC nie omijają polityk. Panel Supabase ma Security Advisor, który wypisuje to, co najpoważniejsze.

Cursor, Windsurf lub Replit z Next.js, Nuxt lub Expressem na Vercelu. Sprawdź, które zmienne środowiskowe mają publiczny prefiks, czy route'y API walidują sesję przy każdym żądaniu, a nie tylko w interfejsie, czy nagłówki bezpieczeństwa są zdefiniowane (vercel.json, next.config lub nuxt.config) i czy na produkcji nie są publikowane source mapy.

Firebase. Zastąp reguły trybu testowego regułami opartymi na request.auth, zarówno w Firestore, jak i w Storage; włącz App Check, żeby tylko Twoja aplikacja mogła korzystać z Twoich usług; i upewnij się, że Cloud Functions robiące coś wrażliwego sprawdzają token użytkownika, zanim zadziałają.

To, że aplikacja „wygląda dobrze", nie znaczy, że jest bezpieczna

Ukrycie przycisku w interfejsie niczego nie chroni: żądanie pozostaje publicznym adresem URL, który każdy może wywołać bezpośrednio z konsoli przeglądarki albo przez curl. Prawdziwe bezpieczeństwo mieszka na serwerze i w bazie danych, nie w tym, co widzi użytkownik. Dlatego sprawdzanie z zewnątrz —tak jak zrobiłby to atakujący— to jedyny sposób, by wiedzieć, co naprawdę jest ujawnione.

Nie wystarczy też zielona kłódka HTTPS. HTTPS szyfruje drogę między przeglądarką a Twoim serwerem; nie mówi nic o tym, czy serwer wydaje dane tym, którym nie powinien. Aplikacja z idealnym certyfikatem i tabelą bez RLS to aplikacja z idealnie zaszyfrowanym wyciekiem.

Jak sprawdzić to samodzielnie w dziesięć minut

Po pierwsze: otwórz stronę i zajrzyj do źródła (prawy przycisk, wyświetl źródło strony). Poszukaj key, secret, sk_, service_role i nazw usług, których używasz. Wszystko, co się tam pojawia, jest publiczne.

Po drugie: przy otwartej aplikacji przejdź do zakładki Network w narzędziach deweloperskich, znajdź żądanie do swojej bazy danych lub API, skopiuj URL i otwórz go w oknie incognito. Jeśli zwraca dane bez sesji, ten endpoint jest otwarty. Zalogowany, usuń filtr użytkownika z URL-a: jeśli zwraca wiersze innych, polityki są złe.

Po trzecie: poproś o nagłówki swojej domeny przez curl -I https://twojadomena.pl i sprawdź, czy pojawiają się Content-Security-Policy, Strict-Transport-Security oraz X-Frame-Options lub frame-ancestors. Jeśli któregoś brakuje, nie jest skonfigurowany.

Po czwarte: spróbuj otworzyć /.env, /.git/config, /config.json i jakiś plik .js.map ze swojego bundle'a. Wszystkie muszą zwrócić 404 lub 403.

Po piąte: utwórz dwa konta testowe i sprawdź, czy żadne nie widzi, nie edytuje ani nie usuwa danych drugiego, łącznie z wgranymi plikami. To najnudniejszy test i ten, który znajduje najwięcej luk.

Jak sprawdzić to w 30 sekund

Scanaris automatyzuje te testy i kilka innych. Skanuje Twoją opublikowaną stronę tylko do odczytu: nie dotyka kodu, niczego nie wstrzykuje ani nie próbuje wykorzystać; patrzy na to, co i tak jest publiczne, tak jak mógłby każdy z zewnątrz. Sprawdza nagłówki, ciasteczka, certyfikat TLS, CORS, sekrety w JavaScripcie, wrażliwe pliki, technologie o znanych wersjach, reguły Supabase, jeśli dasz mu połączenie tylko do odczytu, a do tego jak widzi Cię Google i jak czytają Cię AI.

Każde znalezisko jest uporządkowane według wpływu (najpierw krytyczne), wyjaśnione normalnym językiem i opatrzone promptem naprawczym gotowym do wklejenia w Lovable, Cursora albo narzędzie, którego używasz. Wklej swój URL, poczekaj pół minuty i będziesz wiedzieć, czy możesz spokojnie udostępnić aplikację.

Czego pilnować po starcie

Bezpieczeństwo to nie stan, to nawyk. Każda nowa tabela rodzi się bez RLS, każda nowa funkcja może wsadzić klucz w złe miejsce, a każda zależność się starzeje. Zaplanuj okresowy ponowny skan i przeglądaj różnice, nie cały raport: liczy się to, co otworzyło się od ostatniego razu.

Pilnuj też tego, co nie zależy od kodu: żeby certyfikat i domena nie wygasły, żeby strona odpowiadała i żeby w przeglądarce Twoich użytkowników nie pojawiały się skrypty, których nie umieściłeś. A kiedy coś naprawisz, sprawdź to ponownie z zewnątrz: poprawka liczy się wtedy, gdy skaner przestaje ją widzieć, a nie gdy AI mówi, że gotowe.

Scan my site free

Zgłęb temat dla swojego stacku

Kluczowe kontrole bezpieczeństwa

Powiązane poradniki

Najczęściej zadawane pytania

Czy moja aplikacja w Lovable, Bolt lub Cursor jest bezpieczna?

Może być, ale domyślnie zwykle powstaje z kluczami we frontendzie, niekompletnymi regułami bazy danych i bez nagłówków bezpieczeństwa. Jedyny sposób, by się dowiedzieć, to sprawdzić opublikowaną stronę: Scanaris robi to w 30 sekund, tylko do odczytu.

Czy HTTPS oznacza, że moja aplikacja jest bezpieczna?

Nie. HTTPS szyfruje połączenie między przeglądarką a Twoim serwerem, ale nie powstrzymuje serwera przed wydaniem danych tym, którym nie powinien. Tabela bez RLS albo klucz we frontendzie pozostają ujawnione przy zielonej kłódce.

Czy skanowanie mojej strony jest dla niej niebezpieczne?

Nie. Scanaris wykonuje kontrole tylko do odczytu na już publicznych informacjach (nagłówki, ciasteczka, certyfikaty, dostępne pliki). Nigdy niczego nie modyfikuje, nie usuwa ani nie wstrzykuje. Skanuj tylko strony, które są Twoje albo do których testowania masz uprawnienia.

Czym to się różni od pentestu?

Pentest to dni ręcznej pracy specjalistów, którzy za zgodą próbują wykorzystać luki w Twojej aplikacji. Scanaris to automatyczny, wykonywany tylko do odczytu i trwający sekundy przegląd błędów konfiguracji, które powtarzają się w aplikacjach tworzonych przez AI. Obejmuje to, co zawodzi najczęściej; nie zastępuje pentestu, jeśli przetwarzasz bardzo wrażliwe dane.

Czy muszę znać się na bezpieczeństwie, żeby z tego korzystać?

Nie. Każde znalezisko ma jasne wyjaśnienie i gotowy do wklejenia prompt naprawczy dla AI, więc rozwiążesz je bez bycia ekspertem. Wklej prompt, przejrzyj zmianę i przeskanuj ponownie, żeby potwierdzić, że luka jest zamknięta.

Jak często powinienem skanować ponownie?

Za każdym razem, gdy AI dotknie bazy danych lub doda integrację, i co najmniej raz w tygodniu, jeśli aplikacja jest na produkcji. Płatne plany robią to same i powiadamiają Cię tylko wtedy, gdy coś się zmieni.