← Poradniki stacków

Next.js

Bezpieczeństwo dla twojej aplikacji Next.js

Next.js ułatwia mieszanie kodu serwera i klienta, i właśnie tam wkrada się większość błędów: jedna zmienna NEXT_PUBLIC za dużo, niezabezpieczona API route albo source maps na produkcji. Przeskanuj swoją aplikację i miej pewność w 30 sekund.

Typowe ryzyka przy Next.js

Sekrety w bundlu przez NEXT_PUBLIC

Wszystko z prefiksem NEXT_PUBLIC_ trafia do przeglądarki. Klucz prywatny tam jest na zawsze widoczny dla każdego, kto otworzy DevTools.

API routes bez autoryzacji

API route to publiczny URL. Jeśli tylko ukrywasz przycisk w interfejsie, ale nie sprawdzasz sesji w handlerze, każdy może ją wywołać bezpośrednio.

Source maps i nagłówki domyślnie

Next.js nie dodaje za ciebie nagłówków bezpieczeństwa, a wiele buildów publikuje source maps, które pozwalają odtworzyć twój kod. Oba problemy naprawisz w next.config.

Niemal każda dziura w aplikacji Next.js tworzonej przez AI bierze się z jednego nieporozumienia: niewiedzy, która część kodu działa na serwerze, a która trafia do przeglądarki. Next.js miesza obie w tym samym projekcie, a Cursor, v0 czy Bolt przekraczają tę granicę bez ostrzeżenia. Ten przewodnik wyjaśnia ten model myślowy w pięć minut, omawia, co narzędzia AI robią źle w Next.js, zostawia Ci blok reguł do wklejenia w projekt, prompt do przeglądu i cztery kontrole z zewnątrz. Lista punkt po punkcie, co naprawić, jest w checkliście Next.js przed startem; tutaj jest dlaczego.

Część 1: gdzie działa każda rzecz

Pięć miejsc, dwa światy

W App Routerze Twój kod może żyć w pięciu miejscach: Server Components (tylko serwer, nigdy nie trafiają do przeglądarki), Client Components (oznaczone "use client", wysyłane do przeglądarki w całości), Route Handlers (app/api/.../route.ts, publiczne URL-e), Server Actions (funkcje z "use server", które klient wywołuje przez POST) i middleware (w najnowszych wersjach nazywany proxy), który działa przed każdym żądaniem. Trzy ostatnie plus Server Components to świat serwera; Client Components to świat przeglądarki. Wszystko, co importujesz w Client Component, łącznie ze stałymi i funkcjami pomocniczymi, wędruje do bundle'a.

Co trafia do przeglądarki

  • Zmienne środowiskowe z prefiksem NEXT_PUBLIC_, wbudowane w czasie builda. Pozostałe istnieją tylko na serwerze.
  • Każde dane, które Server Component przekazuje jako prop do Client Component. Jeśli przekazujesz cały obiekt user, podróżuje on z hashem hasła i e-mailem.
  • Pliki z katalogu public/, bez zmian.
  • Source mapy, jeśli włączysz je przez productionBrowserSourceMaps.

Trzy mechanizmy, które zapobiegają przekraczaniu granicy

Pakiet server-only: import 'server-only' na początku pliku sprawia, że build pada, jeśli ktoś zaimportuje go z Client Component. Używaj go we wszystkim, co dotyka bazy danych lub czyta sekrety. Warstwa dostępu do danych: jeden moduł, który centralizuje sprawdzanie sesji i zwraca tylko potrzebne pola (DTO), zamiast odpytywać bazę z każdej strony. I zasada, że każdy punkt wejścia sprawdza sesję: Route Handlers, Server Actions i Server Components czytające prywatne dane, każdy z osobna. Middleware nie zastępuje tej kontroli, co pokazała CVE-2025-29927.

Czego Next.js za Ciebie nie robi

Nie dodaje nagłówków bezpieczeństwa, nie limituje żądań, nie waliduje danych wejściowych Server Actions i nie chroni ścieżek tylko dlatego, że leżą w katalogu o nazwie (admin). To wszystko jest Twoim kodem albo konfiguracją w next.config.

Część 2: co AI robi źle w Next.js

  • Wszystko z "use client". Gdy komponent potrzebuje stanu, AI oznacza go jako kliencki i ciągnie za nim zapytanie do bazy albo klucz API. Rozdziel: komponent serwerowy pobiera dane, kliencki tylko rysuje.
  • Ochrona tylko w middleware. Middleware przekierowuje, gdy nie ma ciasteczka, a handler mu ufa. Sprawdzaj sesję także w handlerze; tego nauczyła CVE middleware'u, a wersje starsze niż 15.2.3 lub 14.2.25 pozostają podatne.
  • Route Handlers i Server Actions bez uwierzytelnienia i walidacji. Server Action to publiczny endpoint, nawet bez widocznego URL-a. Sprawdź, kto wywołuje, i zwaliduj body schematem (zod lub podobnym), zanim cokolwiek zrobisz.
  • Sekrety z publicznym prefiksem. NEXT_PUBLIC_OPENAI_KEY, bo komponent kliencki „go potrzebował". Klucz idzie do Route Handlera, a klient wywołuje handler.
  • remotePatterns z wildcardem. hostname: '**' w konfiguracji obrazów zamienia Twój optymalizator obrazów w otwarte proxy dla dowolnego URL-a.
  • Przekierowania z parametrem. redirect(searchParams.next) bez sprawdzenia, czy cel jest wewnętrzną ścieżką: phishing na Twojej domenie.
  • fetch do URL-i użytkownika. Handler, który pobiera, co mu podadzą, może dotrzeć do wewnętrznych usług Twojej sieci lub dostawcy.
  • dangerouslySetInnerHTML z treścią użytkownika. Klasyczny XSS; jeśli potrzebujesz HTML-a, oczyść go na serwerze.
  • Bez nagłówków i limitów. Ani CSP, ani HSTS, ani X-Frame-Options, i endpoint wywołujący płatny model bez limitu na użytkownika.

Blok reguł dla Twojego projektu

Wklej go do pliku reguł, który czyta Twoje narzędzie (.cursor/rules, AGENTS.md lub odpowiednik), żeby obowiązywał przy każdym generowaniu:

Reguły bezpieczeństwa dla tego projektu Next.js:
- Komponenty są Server Components, chyba że potrzebują stanu lub zdarzeń przeglądarki. Client Component nigdy nie importuje modułów, które sięgają do bazy danych lub czytają process.env bez prefiksu.
- Każdy moduł dotykający bazy danych lub sekretów zaczyna się od import 'server-only'.
- Nigdy nie używaj NEXT_PUBLIC_ dla sekretnego klucza. Wywołania usług z kluczem idą do Route Handlera lub Server Action.
- Każdy Route Handler i każda Server Action sprawdza sesję i waliduje dane wejściowe schematem, zanim cokolwiek zrobi. Middleware nie liczy się jako uwierzytelnienie.
- Przekazuj Client Components tylko potrzebne pola, nigdy cały obiekt użytkownika ani wiersza.
- Przekierowania akceptują tylko wewnętrzne ścieżki zaczynające się od pojedynczego ukośnika.
- images.remotePatterns wymienia konkretne domeny, nigdy wildcard hosta.
- Nie używaj dangerouslySetInnerHTML z treścią użytkownika.
- next.config definiuje nagłówki bezpieczeństwa i nie włącza productionBrowserSourceMaps.

Prompt do przeglądu przed wdrożeniem

Przejrzyj bezpieczeństwo tej aplikacji Next.js i na razie niczego nie zmieniaj. Odpowiedz listą:
1. Client Components, które importują moduły bazy danych, czytają sekrety lub otrzymują jako props obiekty z wrażliwymi polami.
2. Route Handlers i Server Actions bez sprawdzania sesji lub bez walidacji danych wejściowych.
3. Ścieżki, których jedyną ochroną jest middleware.
4. Zmienne NEXT_PUBLIC_ zawierające sekretne klucze.
5. Przekierowania przyjmujące cel od użytkownika, fetch do URL-i użytkownika i użycia dangerouslySetInnerHTML.
6. remotePatterns z wildcardem, włączone productionBrowserSourceMaps i brak nagłówków bezpieczeństwa w next.config.
7. Wersja Next.js i czy jest starsza niż 15.2.3 lub 14.2.25.
Dla każdego punktu zaproponuj dokładną zmianę i poczekaj na moje potwierdzenie.

Sprawdź wynik z zewnątrz

Cztery polecenia na Twoją domenę. Nagłówki i wersja middleware'u:

curl -sI https://twojadomena.com | grep -iE "strict-transport|content-security|x-frame|x-content-type"
curl -s -o /dev/null -w "%{http_code}\n" -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" https://twojadomena.com/dashboard

Jeśli drugie zwraca 200 na ścieżce, która powinna przekierować do logowania, Twoja wersja jest podatna na CVE middleware'u: zaktualizuj dziś. Potem source mapy i ścieżki API, które zdradza bundle:

curl -s https://twojadomena.com | grep -oE '/_next/static/chunks/[^"]+\.js' | head -3
curl -s https://twojadomena.com/_next/static/chunks/main-app-XXXX.js | grep -oE '"/api/[^"]+"' | sort -u

Odpytaj każdą ścieżkę API bez sesji: prawidłowa odpowiedź to 401 lub 403. Scanaris wykonuje te kontrole i około czterdziestu innych w 30 sekund: wykrywa, że aplikacja to Next.js i jaka wersja, testuje nagłówek CVE, szuka sekretów w chunkach, sprawdza, czy source mapy są opublikowane, weryfikuje nagłówki, CSP, ciasteczka, CORS i wystawione pliki, a dla każdego błędu daje fix prompt do wklejenia w Cursorze lub v0. Jeśli wdrażasz na Vercelu, przewodnik po Vercelu obejmuje publiczne podglądy i zmienne środowiskowe.

Często zadawane pytania

Czy Server Actions są domyślnie bezpieczne?

Trudniej je odkryć niż Route Handler, ale są równie publiczne: każdy z identyfikatorem akcji może ją wywołać. Traktuj je jak endpoint: sesja i walidacja wewnątrz funkcji.

Czy middleware wystarczy, żeby chronić panel?

Nie. Przydaje się do szybkiego przekierowania, ale prawdziwa kontrola należy do każdej strony, handlera i akcji. CVE-2025-29927 pozwalała ominąć middleware jednym nagłówkiem; nawet na załatanej wersji zasada pozostaje ta sama.

Czy mogę dalej używać Pages Routera?

Tak, i model jest ten sam: getServerSideProps i pages/api to serwer, reszta to klient. Zwracaj z getServerSideProps tylko to, czego strona potrzebuje, bo wszystko, co zwrócisz, jest serializowane do HTML-a.

Powiązane testy

Czy twoja aplikacja Next.js przechodzi te testy?

Przeskanuj ją za darmo i otrzymaj prompt naprawczy dla każdego znalezionego problemu.

Przeskanuj moją stronę za darmo