flawopen.com/SQL-инъекции в JavaScript/Knex.js
Защищает ли Knex.js от SQL-инъекций?
Представьте SQL как бланк: binding помещает ввод в поле значения, а интерполяция вклеивает его в инструкции. Query builder Knex и knex.raw(sql, bindings) отделяют значения; имена таблиц и столбцов — структура SQL, для них нужен доверенный список.
?? — raw-маркер идентификатора Knex. Он экранирует имя, но не разрешает выбор; используйте список допустимых столбцов.БЕЗОПАСНО — bindings и список
const query = knex.raw(
`SELECT * FROM users WHERE id = ${userId}`
);
// Ввод конкатенируется со строкой 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" ); // Отделяйте значение от синтаксиса SQL. knex.raw("SELECT * FROM users WHERE id = ?", [userId]);
Как bindings Knex защищают значения
Методы .where(), .insert() и .select() отделяют значения от SQL. В raw передавайте значения через bindings: knex.raw("... = ?", [value]). ? обозначает значение, ?? — идентификатор. Не вставляйте ввод интерполяцией в SQL-строку.
Для динамических идентификаторов нужен список
Binding не разрешает произвольные столбцы, таблицы, сортировки, операторы или фрагменты SQL. ?? экранирует идентификатор, но не решает, разрешен ли такой выбор. Сопоставляйте ввод с фиксированным списком до .orderBy(); ключевые слова и операторы задавайте в коде.
Как проверять raw-запросы
Найдите все вызовы knex.raw() и проверьте SQL вместе с bindings. Значения должны передаваться через bindings, а динамические идентификаторы — браться из небольшого списка. Raw-запрос не обязательно уязвим: все зависит от формирования SQL и ввода.
rg -n 'knex\.raw\(' -g '*.js' -g '*.ts' -g '*.mjs' -g '*.cjs' .Вопросы и ответы
Нет. Передавайте недоверенные значения через bindings, например knex.raw("... = ?", [value]). Интерполяция превращает значение в часть SQL-кода. Проверяйте каждый raw-вызов и его вводы.
?? — raw-маркер идентификатора Knex. Он экранирует имя, но не разрешает выбор; используйте список допустимых столбцов.
Источники
- Документация Knex.js — Raw и bindings
- Документация Knex.js — Query builder
- flawopen.com — SQL-инъекции в JavaScript