SQL injection in Prisma è una delle vulnerabilità più comuni, che può compromettere l'integrità dei dati e la riservatezza dell'applicazione. In questo articolo presentiamo un breve modello di minaccia, i meccanismi di funzionamento di Prisma, il confronto tra codice vulnerabile e corretto, una checklist di mitigazione e riferimenti a standard riconosciuti, come OWASP Top 10, CWE e il principio del least‑privilege.
Modello di minaccia – come si genera SQL injection
L'attaccante inietta codice SQL proprio nei dati di input che l'applicazione passa al database senza una corretta validazione o parametrizzazione. Nel contesto di Prisma ciò avviene più spesso usando i metodi queryRaw o executeRaw, che consentono di inserire manualmente frammenti di query. Se vi passiamo stringhe non verificate, apriamo la porta alla manipolazione della query.
Scenario di base:
- L'utente fornisce un valore in un modulo (ad esempio il nome del prodotto).
- L'applicazione costruisce una query SQL inserendo questo valore senza parametrizzazione.
- L'attaccante aggiunge l'istruzione
OR 1=1oDROP TABLE, provocando accesso non autorizzato o distruzione dei dati.
Meccanismo di protezione in Prisma – parametrizzazione e tipizzazione
Prisma ORM genera di default le query utilizzando prepared statements. In questo modo i valori vengono passati come parametri, anziché inseriti direttamente nel testo SQL. In TypeScript, inoltre, utilizziamo i tipi, che limitano la possibilità di iniettare codice indesiderato.
Meccanismi chiave:
- Query Builder – metodi come
findMany,createoupdatecostruiscono le query in modo sicuro. - RAW parametrizzato –
prisma.$queryRaw`SELECT * FROM User WHERE email = ${email}`usa l'interpolazione taggata, che sanitizza automaticamente la variabile. - Tipi Prisma – definiscono la struttura dei dati e impongono il formato corretto dell'input.
Esempio: codice vulnerabile vs codice corretto
Di seguito confrontiamo due frammenti – prima quello pericoloso, poi quello sicuro.
// --- Codice vulnerabile ---
const userInput = req.body.username; // dati dal modulo
const raw = `SELECT * FROM "User" WHERE username = '${userInput}'`;
const result = await prisma.$queryRaw(raw);
Nel esempio sopra userInput viene inserito direttamente nella stringa, consentendo l'iniezione di qualsiasi SQL.
// --- Codice corretto ---
const userInput = req.body.username;
// l'interpolazione taggata garantisce la parametrizzazione
const result = await prisma.$queryRaw`SELECT * FROM "User" WHERE username = ${userInput}`;
L'interpolazione taggata (prisma.$queryRaw`...`) trasforma ${userInput} in un parametro bindato, eliminando il rischio di injection.
Checklist di mitigazione – cosa implementare nel progetto
- Utilizza esclusivamente i metodi dell'API Prisma (
findUnique,createecc.) invece di query RAW manuali. - Se RAW è indispensabile, usa l'interpolazione taggata o passa i parametri come secondo argomento (
prisma.$queryRaw(sql, params)). - Abilita la validazione dello schema di input (ad esempio
zodoclass-validator) prima di inviare i dati al livello di accesso al database. - Limita i privilegi dell'account DB usato dall'applicazione – principio del least‑privilege.
- Monitora i log SQL e rileva pattern inattesi (ad esempio l'uso improvviso di
DROP).
Riferimenti agli standard – OWASP, CWE e least‑privilege
OWASP Top 10 elenca A03:2021 – Injection come una delle categorie più gravi. Nel catalogo CWE, il problema corrispondente è CWE‑89: SQL Injection. Implementando le pratiche sopra, soddisfiamo i requisiti di entrambi gli standard.
Il principio del least‑privilege richiede che l'account del database utilizzato da Prisma possieda solo i permessi necessari (SELECT, INSERT, UPDATE, DELETE sulle tabelle richieste). Evita di concedere il ruolo SUPERUSER o DBA all'applicazione in produzione.
«Le query sicure non sono un optional, sono la base – un codice che non può essere iniettato non richiede correzioni successive.»
Errori comuni e compromessi nella pratica
Le trappole più frequenti:
- Uso di
prisma.$executeRawsenza parametrizzazione – facile da trascurare, soprattutto durante le migrazioni. - Costruzione dinamica di nomi di tabelle o colonne – Prisma non consente la parametrizzazione degli identificatori, quindi è necessario validarli tramite whitelist.
- Abbandono della validazione dell'input a favore della “fiducia” nel frontend – porta a vettori di attacco imprevisti.
Compromessi:
- In alcuni casi è necessario utilizzare
RAWper report complessi. In tal caso è consigliabile isolare questo livello in un servizio separato e avvolgerlo con un ulteriore strato di sanitizzazione. - Se l'applicazione deve gestire query ad‑hoc, considera l'uso di una whitelist di campi e operatori consentiti invece di inserire liberamente il testo.
Esempio pratico – checklist di implementazione
// checklista.ts – implementazione di esempio in TypeScript
import { PrismaClient } from '@prisma/client';
import { z } from 'zod';
const prisma = new PrismaClient();
// 1. Schema di validazione dell'input
const userSchema = z.object({
username: z.string().min(3).max(30),
email: z.string().email(),
});
export async function createUser(payload: unknown) {
// 2. Validazione
const data = userSchema.parse(payload);
// 3. Uso sicuro dell'API Prisma – non RAW
return await prisma.user.create({
data: {
username: data.username,
email: data.email,
},
});
}
// 4. Esempio RAW con parametrizzazione
export async function findUsersByDomain(domain: string) {
const safeDomain = domain.replace(/[^a-zA-Z0-9.-]/g, ''); // sanitizzazione aggiuntiva
return await prisma.$queryRaw`
SELECT * FROM "User" WHERE email LIKE ${'%@' + safeDomain}`;
}
Il codice sopra dimostra come combinare la validazione dello schema, l'uso di un'API sicura e il RAW parametrizzato nei casi in cui è necessario.
Riepilogo e invito alla collaborazione
Applicando le pratiche descritte – parametrizzazione, tipizzazione, validazione e limitazione dei privilegi – elimini il rischio di SQL injection nei progetti basati su Prisma e TypeScript, soddisfacendo al contempo i requisiti di OWASP Top 10 e CWE‑89. Se hai bisogno di un audit di sicurezza, supporto per l'hardening del database o assistenza nell'adozione delle migliori pratiche, contatta Coderia.it – il nostro team di specialisti ti aiuterà a costruire un'architettura backend solida e sicura.



