Как передать значения полей в переменную $ в предварительном запросе?

Как я могу безопасно реализовать подобный запрос?
async read(column, value) {
   return await pool.query(`SELECT * from users WHERE $1=$2`, [column, value])
}

Если я правильно понял, то при использовании запроса
pool.query(`SELECT * from users WHERE ${column}=$1`, [value])
можно прокинуть в column любую команду.
  • 28 октября 2023 г. 16:38
Ответы на вопрос 2
Да, вы правильно поняли. Если вы использовали строковую интерполяцию вместо подстановки значений с помощью плейсхолдеров, вы подвергаете свою программу уязвимостям типа "SQL injection". 

"SQL injection" - это атака, при которой злоумышленник вводит входные данные, которые могут изменить структуру или логику SQL запроса. В вашем случае, если переменная "column" содержит SQL код вместо имени столбца из таблицы, то это может привести к выполнению нежелательных действий в базе данных.

Для обеспечения безопасности и предотвращения "SQL injection", вам следует использовать плейсхолдеры (такие как $1) и передавать значения в виде массива вторым аргументом функции pool.query(). Таким образом, значения будут правильно экранированы и предотвращены потенциальные атаки.

Таким образом, ваш код может быть изменен следующим образом:

async read(column, value) {
   return await pool.query(`SELECT * from users WHERE ${column}=$1`, [value])
}

Теперь вы можете передавать значения безопасно, и ваши запросы будут защищены от "SQL injection".
Параметризация значений возможна, но не применяется для наименований полей и таблиц. Также стоит учитывать, что с каждым новым значением в запросе будет создаваться новый запрос. Валидация значения в поле $(column) необходима, но несложна, так как допустимы только латинские буквы (в обоих регистрах), цифры и подчеркивание. Однако, если используются идентификаторы_в_ковычках, то допустимы любые символы. Как разработчик, вы знаете, какие наименования полей допустимы в запросе и можно избежать ненужных проблем.
Похожие вопросы