SQL‑Injection in Prisma ist eine der häufigsten Schwachstellen, die die Datenintegrität und Vertraulichkeit einer Anwendung gefährden können. In diesem Artikel stellen wir ein kurzes Bedrohungsmodell, die Funktionsweise von Prisma, einen Vergleich von anfälligem und verbessertem Code, eine Checkliste zur Minderung sowie Verweise auf anerkannte Standards wie OWASP Top 10, CWE und das Prinzip der geringsten Rechte vor.
Bedrohungsmodell – wie SQL‑Injection entsteht
Ein Angreifer injiziert eigenen SQL‑Code anstelle von Eingabedaten, die die Anwendung ohne angemessene Validierung oder Parametrisierung an die Datenbank übergibt. Im Kontext von Prisma geschieht dies meist über die Methoden queryRaw oder executeRaw, die das manuelle Einfügen von Query‑Fragmenten erlauben. Wenn wir ihnen nicht verifizierte Zeichenketten übergeben, öffnen wir die Tür für Manipulationen der Abfrage.
Grundlegendes Szenario:
- Ein Benutzer gibt einen Wert in ein Formular ein (z. B. Produktname).
- Die Anwendung erstellt eine SQL‑Abfrage und fügt diesen Wert ohne Parametrisierung ein.
- Der Angreifer fügt die Anweisung
OR 1=1oderDROP TABLEhinzu, was zu unautorisiertem Zugriff oder Datenzerstörung führt.
Schutzmechanismus in Prisma – Parametrisierung und Typisierung
Prisma ORM generiert standardmäßig Abfragen mittels vorbereiteter Anweisungen (prepared statements). Dadurch werden Werte als Parameter übergeben und nicht direkt in den SQL‑Text eingefügt. In TypeScript nutzen wir zusätzlich Typen, die die Möglichkeit einer unerwünschten Code‑Injection einschränken.
Wesentliche Mechanismen:
- Query Builder – Methoden wie
findMany,createoderupdateerzeugen Abfragen sicher. - Parametrisierte RAW –
prisma.$queryRaw`SELECT * FROM User WHERE email = ${email}`verwendet tag‑basierte Interpolation, die die Variable automatisch bereinigt. - Prisma‑Typen – definieren die Datenstruktur und erzwingen das korrekte Eingabeformat.
Beispiel: anfälliger Code vs. verbesserter Code
Unten vergleichen wir zwei Code‑Snippets – zuerst das gefährliche, dann das sichere.
// --- Anfälliger Code ---
const userInput = req.body.username; // Daten aus dem Formular
const raw = `SELECT * FROM "User" WHERE username = '${userInput}'`;
const result = await prisma.$queryRaw(raw);
Im obigen Beispiel wird userInput direkt in die Zeichenkette eingefügt, was eine beliebige SQL‑Injection ermöglicht.
// --- Verbesserter Code ---
const userInput = req.body.username;
// Tag‑basierte Interpolation sorgt für Parametrisierung
const result = await prisma.$queryRaw`SELECT * FROM "User" WHERE username = ${userInput}`;
Tag‑basierte Interpolation (prisma.$queryRaw`...`) wandelt ${userInput} in einen gebundenen Parameter um und eliminiert das Risiko einer Injection.
Checkliste zur Minderung – was im Projekt umzusetzen ist
- Verwende ausschließlich Prisma‑API‑Methoden (
findUnique,createusw.) statt manueller RAW‑Abfragen. - Falls RAW unvermeidlich ist, nutze tag‑basierte Interpolation oder übergebe Parameter als zweites Argument (
prisma.$queryRaw(sql, params)). - Aktiviere die Validierung des Eingabeschchemas (z. B.
zododerclass-validator) bevor Daten an die Datenbank‑Zugriffsschicht übergeben werden. - Begrenze die Berechtigungen des von Prisma genutzten DB‑Kontos – Prinzip der geringsten Rechte.
- Überwache SQL‑Logs und erkenne unerwartete Muster (z. B. plötzliches Auftreten von
DROP).
Verweise auf Standards – OWASP, CWE und least‑privilege
OWASP Top 10 listet A03:2021 – Injection als eine der gravierendsten Kategorien. Im CWE‑Katalog ist das zugehörige Problem CWE‑89: SQL Injection. Durch die Umsetzung der genannten Praktiken erfüllen wir die Anforderungen beider Standards.
Das Prinzip der geringsten Rechte verlangt, dass das von Prisma genutzte Datenbankkonto nur die unbedingt notwendigen Berechtigungen (SELECT, INSERT, UPDATE, DELETE für die erforderlichen Tabellen) besitzt. Vermeide die Vergabe der Rolle SUPERUSER oder DBA an die Produktionsanwendung.
„Sichere Abfragen sind kein Add‑On, sie sind das Fundament – Code, der nicht injiziert werden kann, erfordert keine nachträglichen Korrekturen.“
Typische Fehler und Kompromisse in der Praxis
Häufige Fallen:
- Verwendung von
prisma.$executeRawohne Parametrisierung – leicht zu übersehen, besonders bei Migrationen. - Dynamisches Erzeugen von Tabellen‑ oder Spaltennamen – Prisma erlaubt keine Parametrisierung von Identifikatoren, daher müssen diese in einer Whitelist validiert werden.
- Verzicht auf Eingabevalidierung zugunsten von „Vertrauen“ in das Frontend – führt zu unvorhergesehenen Angriffsvektoren.
Kompromise:
- In manchen Fällen ist es notwendig,
RAWfür komplexe Berichte zu verwenden. Dann sollte diese Ebene in einen separaten Service ausgelagert und mit einer zusätzlichen Sanitisationsebene umschlossen werden. - Wenn die Anwendung Ad‑hoc‑Abfragen unterstützen muss, sollte anstelle von freiem Texteinfügen eine Whitelist zulässiger Felder und Operatoren in Betracht gezogen werden.
Praktisches Beispiel – Implementierungs‑Checkliste
// checklista.ts – Beispielimplementierung in TypeScript
import { PrismaClient } from '@prisma/client';
import { z } from 'zod';
const prisma = new PrismaClient();
// 1. Eingabe‑Validierungsschema
const userSchema = z.object({
username: z.string().min(3).max(30),
email: z.string().email(),
});
export async function createUser(payload: unknown) {
// 2. Validierung
const data = userSchema.parse(payload);
// 3. Sicherer Einsatz der Prisma‑API – kein RAW
return await prisma.user.create({
data: {
username: data.username,
email: data.email,
},
});
}
// 4. Beispiel für RAW mit Parametrisierung
export async function findUsersByDomain(domain: string) {
const safeDomain = domain.replace(/[^a-zA-Z0-9.-]/g, ''); // zusätzliche Sanitisation
return await prisma.$queryRaw`
SELECT * FROM "User" WHERE email LIKE ${'%@' + safeDomain}`;
}
Der obige Code zeigt, wie man Schema‑Validierung, die Nutzung einer sicheren API und parametrisiertes RAW in den Situationen kombiniert, die es erfordern.
Fazit und Einladung zur Zusammenarbeit
Durch die Anwendung der beschriebenen Praktiken – Parametrisierung, Typisierung, Validierung und Rechte‑Beschränkung – eliminierst du das Risiko von SQL‑Injection in Projekten, die auf Prisma und TypeScript basieren, und erfüllst gleichzeitig die Anforderungen von OWASP Top 10 sowie CWE‑89. Wenn du eine Sicherheits‑Audit, Unterstützung beim Hardening der Datenbank oder Hilfe bei der Implementierung von Best Practices benötigst, kontaktiere Coderia.it – unser Expertenteam hilft dir, eine robuste und sichere Backend‑Architektur aufzubauen.



