Я пишу запросы к базе данных с помощью pg-promise. Мои таблицы выглядят так:
Table "public.setting"
│ user_id │ integer │ not null
│ visualisation_id │ integer │ not null
│ name │ character varying │ not null
Table "public.visualisation"
│ visualisation_id │ integer │ not null
│ template_id │ integer │ not null
Я хочу вставить несколько значений в setting
— три из них жестко закодированы, а одно мне нужно найти в visualisation
.
Следующий оператор делает то, что мне нужно, но должен быть уязвим для SQL-инъекций:
var q = "INSERT INTO setting (user_id, visualisation_id, template_id) (" +
"SELECT $1, $2, template_id, $3 FROM visualisation WHERE id = $2)";
conn.query(q, [2, 54, 'foo']).then(data => {
console.log(data);
});
Я знаю, что должен использовать имена SQL, но если я попробуйте использовать их следующим образом, я получаю TypeError: Invalid sql name: 2
:
var q = "INSERT INTO setting (user_id, visualisation_id, template_id) (" +
"SELECT $1~, $2~, template_id, $3~ FROM visualisation WHERE id = $2)";
что, я думаю, неудивительно, поскольку 2
заключено в двойные кавычки, поэтому SQL считает, что это имя столбца.
Если я попытаюсь переписать запрос, чтобы использовать VALUES
, я также получу синтаксическую ошибку:
var q = "INSERT INTO setting (user_id, visualisation_id, template_id) VALUES (" +
"$1, $2, SELECT template_id FROM visualisation WHERE id = $2, $3)";
Как лучше всего вставить сочетание жестко закодированных и переменных значений, избегая при этом рисков SQL-инъекций?
"$1, $2, (SELECT template_id FROM visualisation WHERE id = $2), $3)"
- person Vao Tsun   schedule 24.08.2017$1
и потенциально осуществить SQL-инъекцию, потому что внутренний запрос использует динамические имена столбцов? (Я проверяю существующий код на наличие уязвимостей.) - person Richard   schedule 24.08.2017$1
представляет собой простое значение. Если вы передадите ему любую строку, она будет правильно экранирована как строка, инъекция будет невозможна. - person vitaly-t   schedule 24.08.2017SELECT $1, $2, template_id, $3 FROM visualisation WHERE id = $2
, нет необходимости использовать имена SQL? Зачем тогда они вообще нужны? - person Richard   schedule 24.08.2017