RSTR-ORM-004 — raw SQL template literal
Summary
A raw SQL query is built by interpolating values into a
template literal (`SELECT * FROM users WHERE id = ${id}`)
and passed to knex.raw, sequelize.query, or Prisma's
$queryRawUnsafe. The fact that the syntax looks modern
doesn't change the wire format — it's still string
concatenation, and still SQL-injectable.
Severity
Critical. Full database disclosure, and on some configs
RCE via stored procedures or xp_cmdshell.
Languages
JavaScript / TypeScript.
How to fix it
Use parameter binding:
// Knex
await knex.raw('SELECT * FROM users WHERE id = ?', [id]);
// Sequelize
await sequelize.query('SELECT * FROM users WHERE id = :id', {
replacements: { id },
type: sequelize.QueryTypes.SELECT,
});
// Prisma: use $queryRaw (tagged template — auto-parameterised)
// NOT $queryRawUnsafe
await prisma.$queryRaw`SELECT * FROM users WHERE id = ${id}`;
The Prisma case is subtle: $queryRaw (tagged template
form) IS safe because Prisma parses the ${...}
expressions and binds them as parameters. $queryRawUnsafe
exists explicitly to bypass that — it's named to discourage
exactly the bug this rule catches.