Самый безопасный способ избежать SQL-инъекции для условного запроса с помощью JdbcTemplate?

#java #postgresql #spring-boot

#Ява #postgresql #пружинный ботинок

Вопрос:

Я работаю над проектом Spring Boot, используя JdbcTemplate, чтобы сделать запрос для подключения к PSQL. Есть параметр req, который содержит 3 строки, которые будут отправлены от клиента,

  1. «все»
  2. «0»
  3. «1»

Из кода A я понятия не имею, как обращаться со «всеми», чтобы получить как истинные, так и ложные записи.

A — Застрявшее решение,

 public Listlt;Productgt; getProductsByStatus(String req){  Boolean active = false;   String sql = "SELECT * FROM tbl_products WHERE active = ?";   switch (req) {  case "0":  active = false;  break;  case "1":  active = true;  break;   case "all":  active = ""; // I don't know what to do.  break;   default:  break;  }    Listlt;Productgt; products = new ArrayListlt;gt;();  products = jdbcTemplate.query(sql, new BeanPropertyRowMapperlt;Productgt;(Product.class), active);    return products;  }  

Затем я использую B, который является текущим и рабочим решением, но он небезопасен для SQL-инъекций.

B — Текущее решение,

 public Listlt;Productgt; getProductsByStatus(String req){   String sql = "SELECT * FROM tbl_products";   switch (req) {  case "0":  sql  = " WHERE active = false;";  break;  case "1":  sql  = " WHERE active = true;";  break;   default:  break;  }   Listlt;Productgt; products = new ArrayListlt;gt;();  products = jdbcTemplate.query(sql, new BeanPropertyRowMapperlt;Productgt;(Product.class));    return products;  }  

Существует ли какой-либо более безопасный способ сделать это без риска инъекции SQL ? Большое спасибо.

Комментарии:

1. Второе решение является правильным, и это распространенное решение. Однако обычно это делается с помощью ORM, которые реализуют весь этот динамический SQL за кулисами для вас. Если вы используете обычную JdbcTemplate, это правильный путь.

2. Обратите внимание, что ваше решение B в настоящее время также защищено от внедрения SQL, поскольку в содержимое создаваемого вами SQL не вводится никакой внешний ввод..

3. В растворе в инъекции невозможны. Один оператор просто получает все , а два других не вводят параметр, вместо этого вы перенаправляете все возможные параметры, добавляя. Оба безопасны, но в целом, я думаю , что способом (без ORM) было бы использование a PreparedStatement .

4. Решение B не будет кэшироваться должным образом, поэтому переменные и запросы преобразуются внутри в процедуры для ускорения будущих запросов. Не злоупотребляйте составом запроса. Вместо этого вы могли бы использовать «В состоянии».