PostgresSQL — подготовленный оператор SQL и экранирование строк, предотвращающие атаки SQL-инъекций

Привет, я пишу приложение на С++, используя libpqxx для вставки строк в таблицу Postgres SQL, и записываемые данные вводятся пользователем, поэтому мне нужно защищаться от атак SQL-инъекций. Из того, что я вижу в Интернете, я могу выбрать два подхода:

  1. Подготовленные отчеты
std::string name_str = "Bob";            \\! User input unsafe!!
std::string email_str = "[email protected]"; \\! User input unsafe!!

pqxx::connection con(c_string);

std::string insert_str = "INSERT INTO users(name, email) VALUES ($1, $2)";
con.prepare("insert_to_users", insert_str);

pqxx::work insert_work(con);

insert_work.exec_prepared("insert_to_users", name_str, email_str)
  1. Экранирование строки
std::string name_str = "Bob";            \\! User input unsafe!!
std::string email_str = "[email protected]"; \\! User input unsafe!!

pqxx::connection con(c_string);
pqxx::work insert_work(con);

std::string insert_str = "INSERT INTO users(name, email)"
                          "VALUES ('" + insert_work.esc(name_str) + "' , '" + insert_work.esc(email_str) + "')";

insert_work.exec(insert_str)

Мое приложение не будет поддерживать соединение с базой данных, поэтому подготовленный оператор будет использоваться только один раз, а затем уничтожаться, поэтому использовать подготовленный оператор слишком сложно?

Обеспечивает ли экранирование строк защиту от всех уязвимостей SQL-инъекций? Или есть лучший способ сделать это?


person Steven    schedule 09.06.2020    source источник
comment
Ваш заголовок уже содержит атаки с внедрением SQL. Ответ здесь. Экранирование строк предотвращает окончание нежелательных символов в базе данных, но не обеспечивает защиты от SQL-инъекций, которые связаны с тем, что механизм SQL неправильно интерпретирует конец запроса как другой запрос. Просто погуглив это сразу дал хорошие примеры здесь   -  person Serge Ballesta    schedule 09.06.2020
comment
@SergeBallesta Единственный способ, которым это можно было бы интерпретировать как другой запрос, - это если бы он не был должным образом экранирован с самого начала.   -  person jjanes    schedule 09.06.2020


Ответы (1)


Мое приложение не будет поддерживать соединение с базой данных, поэтому подготовленный оператор будет использоваться только один раз.

Если вы беспокоитесь о производительности, вам следует исправить эту проблему с однократным подключением. И если вы не беспокоитесь о производительности, то какое вам дело до того, что подготовленные операторы «слишком убивают»?

Хотя любой из них должен работать, первый чище и с меньшей вероятностью, что кто-то напортачит в будущем.

person jjanes    schedule 09.06.2020