EMZETT.
Login

Formulare validieren mit Zod und Schemas: Eingaben sicher prüfen

Kurz: Eingaben von Nutzern sind nie vertrauenswürdig; mit Schema-Bibliotheken wie Zod prüft man Form, Typ und Grenzen einmal zentral, im Browser für Komfort und auf dem Server für Sicherheit.

Genauer: Alles, was von außen kommt (Formulare, URL-Parameter, API-Anfragen, Cookies), kann falsch oder bösartig sein. Validierung stellt sicher, dass Daten zur Erwartung passen, bevor das Programm sie nutzt. TypeScript prüft nur zur Entwicklungszeit; zur Laufzeit braucht man Prüfcode.

Im Detail

Zod in Kürze

import { z } from "zod";
 
const Anmeldung = z.object({
  email: z.string().email("Ungültige E-Mail"),
  alter: z.coerce.number().int().min(13).max(120),
  passwort: z.string().min(12),
  agb: z.literal("on", { message: "Bitte zustimmen" }),
});
 
const r = Anmeldung.safeParse(Object.fromEntries(formData));
if (!r.success) return { fehler: r.error.flatten().fieldErrors };
const daten = r.data; // sauber typisiert

Das Schema ist Quelle der Wahrheit: type Anmeldung = z.infer<typeof Anmeldung> erzeugt den TypeScript-Typ. Ähnlich: Valibot, Yup, ArkType, Joi, JSON Schema.

Wo prüfen?

  • Im Browser: schnelle Rückmeldung (HTML-Attribute required, type=email, pattern, plus Schema). Nur Komfort, leicht umgehbar.
  • Immer auch auf dem Server (API-Route, Server Action): Hier liegt die Sicherheit. Nie darauf vertrauen, dass der Browser geprüft hat.
  • Datenbank: Constraints (NOT NULL, UNIQUE, CHECK, Fremdschlüssel) als letzte Verteidigung.
  • Ausgabe: beim Anzeigen escapen (XSS), nicht „sanitisieren und hoffen“.

Gute Regeln

  • Positivliste statt Negativliste: Erlaube bekannte gute Werte (Enum, Muster) statt Schlechtes zu suchen.
  • Grenzen setzen (Länge, Größe, Anzahl, Wertebereich), auch für Datei-Uploads (Typ, Größe, Inhalt prüfen).
  • Typen umwandeln bewusst (coerce), Whitespace trimmen.
  • Fehlermeldungen hilfreich, aber ohne interne Details.
  • Unbekannte Felder ablehnen/entfernen (Mass Assignment verhindern: Nutzer darf nicht istAdmin: true mitsenden).
  • Zeichenkodierung und Normalisierung (E-Mail klein schreiben).
  • Rate Limiting und CAPTCHA/Honeypot gegen Spam.

Zusammenspiel

Mit react-hook-form (+ zodResolver) oder Server Actions (useActionState) bekommt man Formulare mit Fehleranzeige pro Feld. Barrierefreiheit: Fehler mit dem Feld verknüpfen (aria-describedby, aria-invalid), Labels, Fokus auf das erste fehlerhafte Feld. Datenschutz: nur nötige Felder erheben. Prüfe die Validierung mit Unit-Tests (gültige und ungültige Beispiele, Randfälle).

Siehe auch: SQL-Injection, XSS, Rate Limiting, CAPTCHA, TypeScript