Как безопасно экранировать произвольные строки для SQL в PostgreSQL, используя Java - PullRequest
16 голосов
/ 16 марта 2012

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

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's special escape string modifier
  safeStr = "E'" + safeStr + "'";

  return safeStr;
}

Вопросы:

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

Примечания:

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

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

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

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

Ответы [ 2 ]

17 голосов
/ 16 марта 2012

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

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

    $tag$inputString$tag$
    

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

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

1 голос
/ 27 апреля 2017

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...