Kod generowany przez AI działa. Się uruchamia. Wygląda dobrze. Jednak prawie zawsze zawiera te same pięć luk bezpieczeństwa w każdym projekcie. To nie są teoretyczne ryzyka — to konkretne dziury, które pojawiają się w prawie każdej bazie kodu wygenerowanej przez Claude, Cursor, Replit lub Copilota, gdy nie poprosisz jawnie o bezpieczeństwo.

W ciągu ostatniego roku przeanalizowałem dziesiątki projektów zakodowanych "na wyczucie", a te same pięć błędów pojawia się w co najmniej 80% z nich. Każdy z nich zajmuje mniej niż 30 minut do naprawy. Oto co szukać i dokładnie jak to naprawić.

Szybkie fakty
Dla kogo to jest
Dla każdego, kto dostarcza kod generowany przez AI użytkownikom lub klientom
Czas naprawienia wszystkich 5
1–3 godzin w zależności od złożoności
Założony stos techniczny
Next.js/React + Supabase/Firebase + Vercel/Netlify
Powaga
Błędy #1 i #2 mogą ujawnić dane użytkownika — napraw je najpierw
Ostatnia weryfikacja
Kwiecień 2026

Błąd 1: Klucze API zakodowane na stałe w kodzie frontendu

Jak się to dzieje: Mówisz Claude'owi "połącz się z Supabase" lub "dodaj płatności Stripe", a on generuje kod z kluczem API wklejonym bezpośrednio do komponentu React. Kod działa doskonale — a Twój tajny klucz jest widoczny dla każdego, kto otworzy DevTools przeglądarki i sprawdzi kartę Network lub źródło JavaScript.

Dlaczego to niebezpieczne: Twój klucz roli usługi Supabase omija całe bezpieczeństwo bazy danych. Twój tajny klucz Stripe pozwala komuś obciążać karty lub wydawać zwroty. Twój klucz OpenAI pozwala komuś wygenerować tysiące w kosztach połączeń API na Twoim koncie. Boty aktywnie skanują publiczne repozytoria GitHub i wdrażane strony w poszukiwaniu ujawnionych kluczy.

Naprawa: Przenieś każdy tajny klucz do zmiennych środowiskowych. W Next.js, tylko zmienne zaczynające się od NEXT_PUBLIC_ docierają do przeglądarki. Każdy klucz, który daje dostęp do zapisu, dostęp administracyjny lub dostęp finansowy powinien być tylko po stronie serwera.

Po przeniesieniu kluczy do .env.local, przeszukaj całą bazę kodu w poszukiwaniu starych wartości kluczy, aby upewnić się, że ich tam nie ma. Następnie sprawdź historię Git — jeśli klucz był kiedykolwiek zatwierdzony, wciąż znajduje się w historii repo nawet jeśli go usunąłeś. Regeneruj (obróć) każdy klucz, który był kiedykolwiek ujawniony, nawet na krótko.

Czas naprawy: 15–30 minut.

Błąd 2: Tabele Supabase bez bezpieczeństwa na poziomie wierszy

Jak się to dzieje: AI generuje zapytania tworzenia tabel Supabase i operacje CRUD, ale nie włącza Row-Level Security (RLS). Domyślnie tabele Supabase z wyłączonym RLS są w pełni dostępne dla każdego, kto ma adres URL projektu i klucz anonimowy — oba są publiczne (i powinny być).

Dlaczego to niebezpieczne: Bez RLS, Użytkownik A może odpytać dane Użytkownika B. Proste wywołanie fetch z konsoli przeglądarki może pobrać każdy wiersz z każdej tabeli. Cała baza danych jest zasadniczo publiczna.

Jak to zauważyć: Przejdź do pulpitu Supabase → Table Editor. Jeśli jakakolwiek tabela pokazuje "RLS Disabled", masz ten problem. Sprawdź również, czy Twój kod po stronie klienta używa klucza service_role zamiast klucza anon — to jeszcze gorsze.

Naprawa: Włącz RLS na każdej tabeli. Następnie utwórz polityki, które pasują do wzorców dostępu Twojej aplikacji. Najczęstsza polityka: użytkownicy mogą tylko SELECT, INSERT, UPDATE i DELETE wiersze, gdzie auth.uid() = user_id. Przetestuj, logując się jako jeden użytkownik i próbując uzyskać dostęp do danych innego użytkownika przez REST API Supabase.

Czas naprawy: 30–60 minut w zależności od liczby tabel.

Czerpiesz wartość z tego? Publikujemy jeden dogłębny artykuł tygodniowo na temat narzędzi AI, przepływów pracy i praktycznych przewodników bezpieczeństwa. Dołącz do czytających, którzy go otrzymują jako pierwsi →

Błąd 3: Brak walidacji danych wejściowych w formularzach lub trasach API

Jak się to dzieje: AI generuje formularze, które akceptują dowolne dane wejściowe i trasy API, które ufają wszelkim danym przychodzącym. Formularz ma atrybut "required" w HTML, ale brak walidacji po stronie serwera. Ktoś omija formularz całkowicie, wysyłając bezpośrednie żądanie API z dowolnym ładunkiem.

Dlaczego to niebezpieczne: Bez walidacji po stronie serwera atakujący mogą wstrzyknąć skrypty do bazy danych (przechowywany XSS), wysłać nadmierne ładunki, które zerwą Twój serwer, lub przesłać dane, które zepsują logikę aplikacji (jak ujemna cena lub pole e-mail zawierające SQL).

Jak to zauważyć: Otwórz dowolną trasę API lub akcję serwera w bazie kodu. Jeśli używa req.body lub danych formularza bez sprawdzania kształtu, typu i długości każdego pola, masz ten problem.

Naprawa: Dodaj walidację po stronie serwera do każdego punktu końcowego za pomocą biblioteki walidacji schematów. Zod jest standardem dla projektów TypeScript:

TypeScript
import { z } from 'zod';

const taskSchema = z.object({
  title: z.string().min(1).max(200),
  description: z.string().max(2000).optional(),
  priority: z.enum(['low', 'medium', 'high']),
});

// In your API route:
const parsed = taskSchema.safeParse(req.body);
if (!parsed.success) {
  return Response.json({ error: parsed.error }, { status: 400 });
}

W przypadku dowolnego pola, które renderuje się jako HTML (komentarze, opisy, biografie), również oczyszcz dane wyjściowe za pomocą DOMPurify przed wyświetleniem.

Czas naprawy: 30–60 minut.

Błąd 4: Brak ograniczenia szybkości na punktach końcowych API

Jak się to dzieje: AI nigdy nie dodaje ograniczenia szybkości, chyba że go poprosisz. Każda trasa API, którą udostępnia aplikacja, może być atakowana tysiące razy na sekundę przez każdego ze skryptem.

Dlaczego to niebezpieczne: Bez ograniczenia szybkości, ktoś może brute-forcować punkt końcowy logowania, zeskrobować bazę danych, uderzając w punkty końcowe listy wielokrotnie, przytłoczyć serwer (odmowa usługi) lub zużyć przydział API, jeśli Twoje punkty końcowe wywołują usługi zewnętrzne, takie jak OpenAI lub Stripe.

Jak to zauważyć: Jeśli żadna z tras API nie sprawdza, ile żądań wykonał pojedynczy IP lub użytkownik niedawno, nie masz ograniczenia szybkości.

Naprawa: Najprostsze podejście dla aplikacji hostowanych na Vercel to limitator szybkości w pamięci na potrzeby razvoju i limitator oparty na Redis na produkcję. Middleware Edge firmy Vercel może obsługiwać podstawowe ograniczenie szybkości. Upstash Redis (warstwa bezpłatna) z @upstash/ratelimit daje Ci ograniczenie szybkości na poziomie produkcji w małej ilości kodu.

Rozsądny punkt początkowy: 60 żądań na minutę dla uwierzytelnionych użytkowników, 20 na minutę dla użytkowników nieuwierzytelnionych i 5 na minutę dla punktów końcowych logowania/rejestracji (aby zapobiec brute-forcingowi).

Czas naprawy: 20–45 minut.

Błąd 5: Brak kontroli autoryzacji na chronionych stronach i API

Jak się to dzieje: AI generuje piękną stronę pulpitu i trasy API, które zwracają dane użytkownika, ale nie dodaje middleware'u do weryfikacji, że użytkownik jest faktycznie zalogowany. Strona "działa", ponieważ podczas programowania zawsze jesteś zalogowany. W produkcji ktoś może uzyskać dostęp do adresu URL pulpitu bezpośrednio bez logowania lub uderzyć punkt końcowy API i uzyskać dane.

Dlaczego to niebezpieczne: Dostęp bez uwierzytelnienia do chronionych stron oznacza, że każdy może zobaczyć pulpity użytkowników, panele administracyjne lub prywatne dane, po prostu odgadując adres URL. Niezabezpieczone trasy API oznaczają, że każde narzędzie, takie jak Postman lub curl, może pobrać dane bez poświadczeń.

Jak to zauważyć: Otwórz okno przeglądarki w trybie incognito (niezalogowany) i przejdź bezpośrednio do pulpitu, ustawień lub adresów URL administracyjnych. Jeśli widzisz jakąkolwiek zawartość bez przekierowania na stronę logowania, masz ten problem. Następnie spróbuj uderzyć trasy API bezpośrednio — jeśli zwracają dane bez ważnego pliku cookie sesji lub tokena autentykacji, te są niezabezpieczone.

Naprawa: Dodaj middleware autentykacji, który uruchamia się przed każdą trasą chronioną. W Next.js App Router, utwórz middleware.ts w katalogu głównym projektu:

TypeScript
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const session = request.cookies.get('session');
  if (!session) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}

export const config = {
  matcher: ['/dashboard/:path*', '/settings/:path*', '/api/protected/:path*'],
};

Dostosuj matcher do wszystkich tras, które powinny wymagać uwierzytelnienia. Przetestuj w trybie incognito po wdrożeniu.

Czas naprawy: 15–30 minut.

Jak zapobiec tym błędom w przyszłych projektach

Wzorzec jest jasny: AI generuje kod, który działa funkcjonalnie, ale pomija bezpieczeństwo, ponieważ go nie poprosiłeś. Naprawa polega na poproszeniu go na górze.

Dodaj to na koniec swojego początkowego promptu dla każdego projektu kodowanego "na wyczucie":

Fragment promptu
SECURITY REQUIREMENTS:
- All secrets in environment variables (never hardcoded)
- Supabase RLS enabled on all tables with per-user policies
- Server-side input validation on every API route (use Zod)
- Rate limiting on all public endpoints
- Authentication middleware on all protected routes
- No service role key in client-side code

To nie złapie wszystkiego, ale eliminuje pięć najczęstszych luk w bezpieczeństwa przy pierwszym przejściu zamiast wymagać czyszczenia później.

Jeśli chcesz stać się lepszy w pisaniu promptów, które od razu produkują bezpieczniejszy kod z AI, nasz darmowy optimizer promptów może Ci pomóc w strukturyzacji instrukcji. A dla pełnego przeglądu bezpieczeństwa, zobacz nasz przewodnik krok po kroku: Jak zabezpieczyć aplikację kodowaną "na wyczucie" przed przekazaniem jej klientom.

To jest to, co robimy każdy tydzień. Jeden dogłębny artykuł na temat narzędzi AI, przepływów pracy i szczerych opinii — bez hype'u, bez wypełniaczy. Dołącz do nas →

Ujawnienie: Niektóre linki w tym artykule to linki partnerskie. Rekomendujemy tylko narzędzia, które osobiście testowaliśmy i regularnie używamy. Zobacz naszą pełną politykę ujawniania.