import { auth } from "@/auth";
import { z } from "zod";
import { prisma } from "@/lib/db";
const bioSchema = z.string().max(500).trim();
// AȘA DA: Validare completă, autentificare și query parametrizat
export async function updateProfile(rawBio: unknown) {
const session = await auth();
if (!session?.user?.id) {
throw new Error("Neautorizat");
}
// 1. Validăm inputul cu Zod
const safeBio = bioSchema.parse(rawBio);
// 2. Folosim ORM-ul securizat (evită SQL injection)
return await prisma.user.update({
where: { id: session.user.id },
data: { bio: safeBio },
// 3. Returnăm doar ce este strict necesar pe client
select: {
id: true,
bio: true
}
});
}Salutare! Hai să vorbim direct despre securitate în Next.js, mai ales acum că Server Actions și React Server Components (RSC) au devenit noul standard de dezvoltare. Am trecut recent printr-un audit tehnic pe un proiect cu 15.000 de utilizatori activi și mi-am dat seama că mulți facem aceleași greșeli, crezând că framework-ul ne salvează de toate problemele. Spoiler: nu o face.
Fiecare paradigmă nouă vine cu riscuri noi. În Next.js, granița dintre server și client este extrem de subțire, iar asta deschide ușa unor vulnerabilități clasice, dar mascate sub haine noi.
1. Server Actions și noul val de CSRF / Data Leakage
Mulți colegi cred că dacă Next.js se ocupă de protecția CSRF în mod automat la Server Actions (verificând header-ul Origin), suntem complet în siguranță. Este parțial adevărat, dar protecția asta funcționează doar pentru request-uri de tip POST. Dacă ai endpoint-uri custom de API în /api/route.ts folosite pentru GET-uri care modifică starea sau dacă ai configurat CORS aiurea cu wildcard-uri, ești expus.
Dar cel mai mare risc în Next.js este data leakage-ul. Când returnezi un obiect direct din baza de date dintr-un Server Component către un Client Component, Next.js serializează tot acel obiect în payload-ul JSON care ajunge în browser.
Am pățit ca un dev să trimită în PR un simplu return user; unde obiectul conținea hash-ul parolei și token-ul de Stripe, doar pentru că pe client avea nevoie doar de user.name. Trade-off-ul e clar: e super comod să pasăm obiecte întregi, dar dacă nu folosim un DTO (Data Transfer Object) sau un select explicit în baza de date, expunem secrete direct în sursa paginii.
2. XSS-ul nu a murit, doar s-a mutat în Hydration
React ne protejează implicit de Cross-Site Scripting (XSS) prin escaping automat, dar tentația de a folosi dangerouslySetInnerHTML rămâne uriașă, mai ales când randezi conținut dintr-un CMS extern (cum ar fi Strapi sau Sanity).
Dacă editorul din CMS este compromis sau dacă un utilizator rău intenționat reușește să injecteze un script în baza de date, acel script va rula direct în browserul vizitatorilor tăi. O altă greșeală frecventă este trecerea parametrilor din URL (searchParams) direct în atribute nesanitizate ale componentelor de client.
3. SQL Injection în era ORM-urilor
Nimeni nu mai scrie SQL brut în 2026, nu? Teoretic, Prisma sau Drizzle ne protejează de SQL injection prin utilizarea query-urilor parametrizate sub capotă. Practic însă, când query-urile devin complexe (de exemplu, la un sistem de căutare avansat cu filtre dinamice), mulți developeri își pierd răbdarea și apelează la metode de tipul $queryRaw sau sql.raw() din Drizzle.
Când vezi într-un PR concatenare de string-uri în interiorul unei metode de bază de date, trebuie să oprești build-ul imediat. Este rețeta perfectă pentru un dezastru.
Checklist rapid pentru review-ul de PR
Când fac review pe o aplicație Next.js, am trei reguli de aur pe care le urmăresc obsesiv:
- Verifică fiecare Server Action: Are validare de input făcută cu Zod sau schema validation? Are verificare de sesiune în interiorul acțiunii (nu doar la nivel de pagină)?
- Caută
dangerouslySetInnerHTML: Dacă există, insist să văd o librărie de sanitizare precumisomorphic-dompurifyaplicată pe acel input. - Analizează payload-ul RSC: Asigură-te că datele trimise de la server la client sunt doar cele strict necesare pentru randare, fără secrete ascunse în obiecte mari.
Securitatea nu mai este doar treaba echipei de DevOps sau a unui tool de scanare automată în CI/CD. Voi cum vă asigurați că Server Actions nu devin o gaură de securitate în proiectele voastre?