gotchajavascriptCritical
SQL Injection Prevention via ORM Parameterization
Viewed 0 times
sql injectionparameterized queryprismasequelizeraw queryormbind parameters
Problem
Even when using an ORM, manually interpolating user input into raw query strings bypasses the ORM's parameterization and reintroduces SQL injection.
Solution
Always use parameterized query methods. In Prisma use the Prisma.sql template tag for raw queries. In Sequelize use replacements or bind parameters, never string interpolation.
Why
Parameterized queries send the SQL structure and user data as separate messages to the database driver. The database treats user data as a literal value and never interprets it as SQL.
Gotchas
- Prisma's db.$queryRaw with Prisma.sql is safe, but db.$queryRawUnsafe with string interpolation is not
- Sequelize's Model.findAll with a where clause using objects is safe; Model.query with a concatenated string is not
- Column names and table names cannot be parameterized—validate them against a strict allowlist if dynamic
- ORDER BY clauses are commonly overlooked injection points when the sort column comes from user input
Code Snippets
Safe raw query in Prisma using Prisma.sql template tag
const { PrismaClient, Prisma } = require('@prisma/client');
const prisma = new PrismaClient();
// Safe: uses parameterized query
async function findUserByEmail(email) {
return prisma.$queryRaw`SELECT id, name FROM users WHERE email = ${email}`;
}
// Also safe: ORM where clause
async function findUserById(id) {
return prisma.user.findUnique({ where: { id } });
}
// Safe dynamic ORDER BY via allowlist
const ALLOWED_SORT = new Set(['name', 'createdAt', 'email']);
async function listUsers(sortBy) {
const col = ALLOWED_SORT.has(sortBy) ? sortBy : 'createdAt';
return prisma.user.findMany({ orderBy: { [col]: 'asc' } });
}Revisions (0)
No revisions yet.