SQL injection in Prisma – guida pratica per ingegneri Node.js

Scopri come proteggere Prisma da SQL injection nelle applicazioni Node.js usando TypeScript e le migliori pratiche OWASP.

SQL injection w Prisma – praktyczny przewodnik dla inżynierów Node.js

SQL injection in Prisma è un problema che può verificarsi anche con ORM moderni, se non si adottano le pratiche corrette. In questo articolo presentiamo il modello di minaccia, i meccanismi di Prisma, il confronto tra codice vulnerabile e corretto e una checklist di mitigazione basata su OWASP Top 10, CWE e il principio del minimo privilegio.

Modello di minaccia – come nasce una SQL injection

L'attacco di SQL injection consiste nell'iniettare una porzione non autorizzata di linguaggio SQL nella query generata dall'applicazione. Nel contesto di Prisma ciò avviene più spesso quando lo sviluppatore utilizza le cosiddette raw queries o interpola variabili in stringhe senza validazione. Il meccanismo di Prisma sanitizza i parametri passati come oggetti, ma non protegge dall'uso pericoloso di prisma.$queryRaw o prisma.$executeRaw con formattazione errata.

Come Prisma e TypeScript aiutano a eliminare il rischio

Prisma offre due livelli di protezione: statico (tipi TypeScript) e runtime (query parametrizzate). I tipi garantiscono che i campi passati alle query esistano nello schema, mentre il runtime converte automaticamente i valori in parametri bind, eliminando la possibilità di iniezione SQL. È fondamentale utilizzare costantemente i metodi findUnique, findMany, create ecc., invece di costruire manualmente le query.

Esempio: codice vulnerabile vs. codice corretto

Di seguito presentiamo due frammenti – il primo viola le regole di sicurezza, il secondo sfrutta appieno il potenziale di Prisma e TypeScript.

// codice vulnerabile – uso di $queryRaw con interpolazione di stringa
const userId = req.query.id; // proveniente dall'utente
const result = await prisma.$queryRaw(`SELECT * FROM "User" WHERE id = ${userId}`);

In questo esempio il valore userId viene inserito direttamente nella query, consentendo a un attaccante di sostituirlo con 1; DROP TABLE "User";. Il modo corretto è usare parametri bind:

// codice corretto – parametro bind
const userId = Number(req.query.id);
if (Number.isNaN(userId)) {
  throw new Error('Invalid user id');
}
const result = await prisma.$queryRaw`
  SELECT * FROM "User" WHERE id = ${userId}`;

Prisma converte automaticamente ${userId} in placeholder $1 e invia il valore separatamente, eliminando il rischio di iniezione.

Checklist di mitigazione – cosa fare per non commettere errori

  • Utilizza esclusivamente i metodi ORM (find*, create*, update*, delete*) invece di $queryRaw e $executeRaw.
  • Quando è necessario usare una raw query, applica sempre la parametrizzazione (prisma.$queryRaw`...${value}`).
  • Valida e converte tutti i dati di input (es. Number(), zod, class-validator).
  • Abilita i privilegi minimi nel database (least‑privilege) – l'account Prisma non dovrebbe avere permessi DDL.
  • Scansiona regolarmente il codice alla ricerca di CWE‑89 (SQL Injection) con strumenti SAST.

Riferimenti agli standard – OWASP, CWE e principio least‑privilege

OWASP Top 10 classifica SQL injection come A03 – “Injection”. CWE‑89 descrive dettagliatamente la tecnica di iniezione e le contromisure consigliate, inclusi l'uso di statement preparati e l'evitare la costruzione dinamica di query. Il principio least‑privilege impone l'assegnazione di privilegi minimi all'account di database – in pratica l'account Prisma dovrebbe avere solo SELECT, INSERT, UPDATE, DELETE sulle tabelle necessarie.

“La sicurezza non è un test una tantum, ma un processo continuo – ogni nuovo frammento di codice è un potenziale vettore di attacco.”

Errori comuni e compromessi

L'errore più frequente è dipendere da “stringhe magiche” nella logica di business e inserirle successivamente in raw queries. Un altro problema è la mancanza di validazione dei tipi durante la conversione dei dati di input, che porta a NaN inattesi e, di conseguenza, al fallback su stringhe. Un compromesso può essere l'uso di prisma.$queryRawUnsafe quando non esiste un'alternativa, ma in tal caso è necessario garantire manualmente la sanitizzazione e limitare l'accesso a tale funzione a un unico modulo ben testato.

Checklist pratica di implementazione

  • Audit del codice per l'uso di $queryRaw e $executeRaw.
  • Imponi il typing di tutti i parametri in TypeScript (es. type UserId = number).
  • Configura lo schema Prisma con i ruoli appropriati – @@map e @@id non devono essere modificati a runtime.
  • Implementa test di integrazione che tentano di iniettare stringhe malevole negli endpoint.
  • Imposta regole CI/CD che bloccano il merge al rilevamento di CWE‑89 nei risultati SAST.

Adottando queste pratiche, ridurrai al minimo il rischio di SQL injection nelle applicazioni Node.js che utilizzano Prisma e TypeScript, mantenendo al contempo alte prestazioni e leggibilità del codice.

Se hai bisogno di supporto per l'hardening del livello dati, audit di sicurezza o implementazione CI/CD conforme a OWASP, contatta Coderia.it – ti aiuteremo a costruire soluzioni backend solide e sicure.

Cominciamo

Hai un progetto in mente?

Descrivilo in poche righe: rispondo entro 24 ore con un preventivo gratuito e una proposta di stack.