Veiligheidsgids · Veilig vibecoden
Ingelogd zijn betekent niet dat je alles mag. Het verschil, en de fout die in veel AI-gegenereerde apps zit.
Authenticatie is vaststellen wie iemand is: inloggen. Autorisatie is bepalen wat die persoon mag: alleen zijn eigen facturen zien, niet die van anderen.
AI-gegenereerde code regelt het inloggen vaak netjes, maar vergeet bij elke afzonderlijke route te controleren of de ingelogde gebruiker deze specifieke gegevens mag zien of wijzigen. Het gevolg: door een ID in de URL aan te passen zie je gegevens van anderen.
Een route als /api/facturen/123 geeft factuur 123 terug aan iedereen die ingelogd is, ook als die van iemand anders is.
Een verborgen knop is geen beveiliging. Een aanvaller roept de API direct aan.
Bij diensten waarbij de browser direct met de database praat, moeten toegangsregels (zoals row level security) aan staan, anders is alles leesbaar.
Wachtwoorden in platte tekst of met een zwakke hash zijn bij een lek direct bruikbaar. Gebruik een bewezen auth-oplossing.
De query zoekt alleen binnen de facturen van de ingelogde gebruiker. Een ID van iemand anders levert niets op.
Loop dit na voordat je verder gaat of iets online zet.
export async function GET(req: Request, { params }) {
const session = await getSession();
if (!session) return new Response("Unauthorized", { status: 401 });
// Geeft elke factuur terug, ook die van anderen
const invoice = await db.invoice.findUnique({ where: { id: params.id } });
return Response.json(invoice);
}export async function GET(req: Request, { params }) {
const session = await getSession();
if (!session) return new Response("Unauthorized", { status: 401 });
const invoice = await db.invoice.findFirst({
where: { id: params.id, ownerId: session.userId },
});
// 404 in plaats van 403, zodat je niet verraadt dat het ID bestaat
if (!invoice) return new Response("Not found", { status: 404 });
return Response.json(invoice);
}