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.

References