Подтвердить что ты не робот

Как безопасно избежать произвольных строк для SQL в PostgreSQL с помощью Java

У меня есть специальный случай, требующий, чтобы я генерировал часть предложения SQL WHERE из введенных пользователем входных значений. Я хочу предотвратить любую уязвимость SQL Injection. Я придумал следующий код:

private String encodeSafeSqlStrForPostgresSQL(String str) {

  //Replace all apostrophes with double apostrophes
  String safeStr = str.replace("'", "''");

  //Replace all backslashes with double backslashes
  safeStr = safeStr.replace("\\", "\\\\");

  //Replace all non-alphanumeric and punctuation characters (per ASCII only)
  safeStr = safeStr.replaceAll("[^\\p{Alnum}\\p{Punct}]", "");

  //Use PostgreSQL special escape string modifier
  safeStr = "E'" + safeStr + "'";

  return safeStr;
}

Вопросы:

  • Вы видите какие-либо проблемы?
  • Можете ли вы предоставить лучшее решение?
  • Существуют ли какие-либо существующие библиотеки, чтобы помочь с этим?

Примечания:

  • Это общий вопрос о SO и в других местах, но единственный ответ, который я видел, - всегда использовать PreparedStatements. Fwiw, я использую JasperReports. Я хочу сохранить запрос внутри JasperReports. Встроенные функции Jasper для обработки параметров запроса (включая функции X {}) недостаточны для того, что мне нужно параметризовать. Я мог бы попытаться создать пользовательский Jasper QueryExecutor, который позволил бы мне вводить мои собственные функции X {}, но это сложнее, чем просто генерировать предложение динамического SQL where с синтаксисом Jasper $P! {}.

  • Я просмотрел библиотеки OWASP. У них еще нет кодека PostgresSQL. Я смотрел на OracleCodec, хотя его экранирование казалось упрощенным. Я не уверен, что это поможет предотвратить атаки SQL-инъекций.

  • В моем коде я добавляю E так, чтобы не зависел от установки PostgreSQL standard_conforming_strings. В идеале мне бы не пришлось добавлять это, и тогда функция не должна была быть специфичной для PostgreSQL. Дополнительная информация: http://www.postgresql.org/docs/9.0/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE.

В идеале мне хотелось бы, чтобы более общее и надежное решение, которое я знал, было бы безопасным и поддерживало бы все возможные строки UTF-8.

4b9b3361

Ответ 1

Самый простой способ - использовать PostgreSQL Долларовое предложение в сочетании с небольшим случайным тегом:

  • Для каждого вызова вычисляйте небольшой случайный тег (например, 4 символа) (избыточно)
  • Посмотрите, является ли тэг quote частью входной строки.
  • Если это так, пересчитайте новый случайный тег.
  • В противном случае создайте свой запрос следующим образом:

    $tag$inputString$tag$
    

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

В зависимости от ваших требований безопасности это может сделать работу или нет.: -)

Ответ 2

Я спросил здесь > аналогичный вопрос, но я думаю, что лучше всего использовать org.postgresql.core.Utils.escapeLiteral. Это библиотека Postgres, поэтому ее использование должно быть безопасным. Если/когда Postgres добавляет новые разделители строк, этот метод должен быть обновлен.