SQL injection у Prisma – це проблема, яка може виникнути навіть при сучасних ORM, якщо не застосувати належні практики. У цій статті ми розглядаємо модель загрози, механізми роботи Prisma, порівняння вразливого та виправленого коду та чек‑лист мітигації, заснований на OWASP Top 10, CWE та принципі найменших привілеїв.
Модель загрози – як виникає SQL injection
Атака SQL injection полягає у впровадженні неавторизованого фрагмента мови SQL у запит, що генерується застосунком. У контексті Prisma це найчастіше трапляється, коли розробник користується так званими raw запитами або інтерполює змінні у рядках без валідації. Механізм Prisma сам по собі санітизує параметри, передані як об’єкти, але не захищає від небезпечного використання prisma.$queryRaw чи prisma.$executeRaw з неправильним форматуванням.
Як Prisma і TypeScript допомагають усунути ризик
Prisma пропонує два рівні захисту: статичний (типи TypeScript) та runtime (параметризовані запити). Типи гарантують, що поля, передані у запити, існують у схемі, а runtime автоматично перетворює значення у прив’язані параметри, що усуває можливість ін’єкції SQL‑коду. Ключове – послідовно використовувати методи findUnique, findMany, create тощо, замість ручного формування запитів.
Приклад: вразливий vs. виправлений код
Нижче наведено два фрагменти – перший порушує правила безпеки, другий використовує повний потенціал Prisma і TypeScript.
// вразливий код – використання $queryRaw з інтерполяцією рядка
const userId = req.query.id; // отримане від користувача
const result = await prisma.$queryRaw(`SELECT * FROM "User" WHERE id = ${userId}`);
У цьому прикладі значення userId вставляється безпосередньо у запит, що дозволяє атакуючому підмінити його, наприклад, на 1; DROP TABLE "User";. Правильний спосіб – використання прив’язаних параметрів:
// виправлений код – прив’язаний параметр
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 автоматично замінює ${userId} на плейсхолдер $1 і передає значення окремо, що усуває можливість ін’єкції.
Checklist мітигації – що зробити, щоб не помилитися
- Використовуйте лише методи ORM (find*, create*, update*, delete*) замість
$queryRawі$executeRaw. - Якщо треба застосувати raw‑query, завжди використовуйте параметризацію (
prisma.$queryRaw`...${value}`). - Валідуйте і конвертуйте всі вхідні дані (наприклад,
Number(),zod,class‑validator). - Увімкніть у базі мінімальні привілеї (least‑privilege) – обліковий запис Prisma не повинен мати прав DDL.
- Регулярно скануйте код на предмет CWE‑89 (SQL Injection) за допомогою SAST.
Посилання на стандарти – OWASP, CWE та принцип least‑privilege
OWASP Top 10 класифікує SQL injection як A03 – «Injection». CWE‑89 детально описує техніку ін’єкції та рекомендовані заходи, включаючи використання підготовлених виразів і уникання динамічного формування запитів. Принцип least‑privilege вимагає надати базі мінімальні права – на практиці обліковий запис Prisma має мати лише SELECT, INSERT, UPDATE, DELETE на потрібних таблицях.
«Безпека не є одноразовим тестом, а постійним процесом – кожен новий фрагмент коду це потенційний вектор атаки.»
Типові помилки та компроміси
Найпоширеніша помилка – залежність від «магічних» рядків у бізнес‑логіці та їх подальше вставлення у raw‑queries. Інша проблема – відсутність валідації типів при конвертації вхідних даних, що призводить до неочікуваних NaN і, як наслідок, до fallback‑у на рядки. Компромісом може бути використання prisma.$queryRawUnsafe у випадках, коли альтернативи немає, але тоді треба вручну забезпечити санітизацію і обмежити доступ до такої функції одним добре протестованим модулем.
Практичний чек‑лист впровадження
- Аудит коду на використання
$queryRawі$executeRaw. - Забезпечте типізацію всіх параметрів у TypeScript (наприклад,
type UserId = number). - Налаштуйте Prisma schema з відповідними ролями –
@@mapі@@idне повинні змінюватися у runtime. - Впровадьте інтеграційні тести, які намагаються ін’єктувати шкідливі рядки у ендпоінти.
- Встановіть правила CI/CD, які блокують merge при виявленні CWE‑89 у результатах SAST.
Застосовуючи вищеперелічені практики, ви мінімізуєте ризик SQL injection у застосунках Node.js, що працюють з Prisma і TypeScript, і одночасно збережете високу продуктивність і читабельність коду.
Якщо потрібна допомога у зміцненні шару даних, аудиті безпеки або впровадженні CI/CD за стандартами OWASP, звертайтеся до Coderia.it – ми допоможемо створити надійні та безпечні бекенд‑рішення.



