flawopen.com/SQL Injection en JavaScript/Knex.js
¿Knex.js es seguro frente a SQL Injection?
Imagina SQL como un formulario impreso: un binding pone la entrada en un campo de valor; la interpolación la pega a las instrucciones. El query builder de Knex y knex.raw(sql, bindings) separan los valores, pero los nombres de tablas y columnas son estructura SQL y requieren una lista permitida confiable.
?? es el marcador raw de identificador de Knex. Cita el identificador, pero no autoriza la elección; usa una lista permitida.SEGURO — bindings y lista permitida
const query = knex.raw(
`SELECT * FROM users WHERE id = ${userId}`
);
// La entrada se concatena al SQL. const allowedSortColumns = new Set(["created_at", "name"]); const rows = await knex("users") .where("id", userId) .orderBy( allowedSortColumns.has(requestedSort) ? requestedSort : "created_at", requestedDirection === "asc" ? "asc" : "desc" ); // Mantén el valor separado de la sintaxis SQL. knex.raw("SELECT * FROM users WHERE id = ?", [userId]);
Cómo protegen los bindings de Knex los valores
Métodos como .where(), .insert() y .select() separan valores del SQL generado. En expresiones raw, pasa los valores como bindings: knex.raw("... = ?", [value]). ? representa un valor y ??, un identificador. No interpoles entradas en una cadena SQL.
Los identificadores dinámicos requieren una lista permitida
Un binding no autoriza columnas, tablas, ordenaciones, operadores ni fragmentos SQL elegidos por el usuario. ?? cita un identificador, pero no decide si se debe permitir. Asocia la opción a una lista fija antes de usar .orderBy(); deja las palabras clave y operadores fijos en el código.
Cómo auditar consultas raw
Busca cada llamada a knex.raw() y revisa juntos la cadena SQL y sus bindings. Comprueba que los valores usan bindings y que los identificadores dinámicos proceden de una lista pequeña. Raw no implica vulnerabilidad; depende de cómo se construyan el SQL y las entradas.
rg -n 'knex\.raw\(' -g '*.js' -g '*.ts' -g '*.mjs' -g '*.cjs' .Preguntas frecuentes
No. Usa bindings para valores no confiables, por ejemplo knex.raw("... = ?", [value]). Interpolar un valor en la cadena lo convierte en parte del SQL. Revisa cada llamada raw y sus entradas.
?? es el marcador raw de identificador de Knex. Cita el identificador, pero no autoriza la elección; usa una lista permitida.
Referencias
- Documentación Knex.js — Raw y bindings
- Documentación Knex.js — Query builder
- flawopen.com — SQL Injection en JavaScript