2013-07-08 5 views
0

Это одна из проблем с конфликтом ключевого слова в модуле запроса моего приложения, пожалуйста, посмотрите, можете ли вы сказать мне умное решение.Интеллектуальное решение SQL-инъекции

Во-первых, в модуле запроса, каждое условие запроса содержит три части в интерфейсе:

имя 1.field, его значение фиксируется, например, происхождение, finalDest ...

2.operator, это выбранный список, который включает «как», «не нравится», «in», «not in», «=», «! =»

3.значение, эта часть вводится пользователем. end, он будет собирать инструкцию SQL в соответствии с критериями запроса пользовательского интерфейса, например, если пользователь вводит/выбирает следующие данные в пользовательском интерфейсе

Field Name  Operator  Value 
origin   like   CHI 
finalDest  in    SEL 

В заднем конце, он будет генерировать следующий SQL:

выберите * от заказа, где происхождения, как '% CHI%' и finalDest в ('SEL').

Но есть ошибка, например, если пользователь вводит некоторый специальный символ в «значение», например «« »,« _ »и т. Д., Это приведет к тому, что сгенерированный SQL также содержит« или _ », например:

выберите * from Booking, где происхождение типа '% C_HI%' и finalDest in ('S'EL').

вы могли видеть, как есть специальный символ «где» блок, то SQL не может быть выполнено

Для этой задачи, мое решение добавить экранирующий символ «/» перед специальным символом перед но я знаю, что это просто «или», которые будут противоречить ключевым словам SQL, знаете ли вы, есть ли какие-либо другие аналогичные символы, которые мне нужно обработать, или у вас есть идея, которая может избежать инъекции.

Извините, забыли, сказал вам, какой язык я использую, я использую java, DB - это mysql, я также использую hibernate, многие люди говорят, почему я не использовал PreparedStatement, это немного сложно, просто Speakin g, в моей компании у нас был FW, называемый динамическим запросом, мы предварительно определили фрагмент SQL в XML-файле, тогда мы собираем SQL в соответствии с прохождением UI в критериях с выражением jxel, поскольку SQL является своего рода предопределенные вещи, я боюсь, если вы измените использование PreparedStatement, это потребует значительных изменений для нашей FW, поэтому нам очень важно решить проблему SQL-инъекции простым способом.

+0

Предположительно вы отправляете этот запрос на сервер, сервер должен иметь схему аутентификации, которая только может получить доступ к клиенту, а клиент должен дезинфицировать его ввод базы данных. – awiebe

+0

Какой серверный язык вы используете? –

+0

HI, я использую mysql5 + hibernate, но я предположил, что он не должен зависеть от mysql и должен быть общим кросс-платформенным оператором SQL. – Chailie

ответ

1
0 An ASCII NUL (0x00) character. 
' A single quote (“'”) character. 
" A double quote (“"”) character. 
b A backspace character. 
n A newline (linefeed) character. 
r A carriage return character. 
t A tab character. 
Z ASCII 26 (Control+Z). See note following the table. 
\ A backslash (“\”) character. 
% A “%” character. See note following the table. 
_ A “_” character. See note following the table 

Reference

Stack Similar Question

+0

не уверен 0, двойная кавычка будет противоречить стандарту SQL. – Chailie

2

Код должен начинаться с попытки остановить SQL-инъекцию на стороне сервера до отправки любой информации в базу данных. Я не уверен, какой язык вы используете, но обычно это достигается путем создания инструкции, содержащей какие-либо переменные связывания. В Java это PreparedStatement, другие языки содержат похожие функции.

Использование переменных привязки или параметров в инструкции будет использовать встроенную защиту от SQL-инъекции, которая, честно говоря, будет лучше, чем все, что вы или я пишем в базе данных. Если вы выполняете конкатенацию String на стороне сервера, чтобы сформировать полный оператор SQL, это индикатор риска инъекции SQL.

+0

Да, вы правы, но мы где мы находимся, если вы измените использование PreparedStatement, i подумайте, что это повлияет на многие кодировки, которые мы предположили, что они уже стабильны. Вам нужно сделать это с помощью умного решения, чтобы исправить проблему инъекций, независимо от использования escape-символа или чего-то еще, я надеюсь, что изменение не будет слишком большим , – Chailie

+0

@Chailie Если вы используете спящий режим, он уже должен использовать PreparedStatements –

+0

, что мы написали так: em = emf.createEntityManager(); Запрос запроса = em.createNativeQuery (sql); ret = query.getResultList(), но он будет иметь следующее исключение, если я напечатаю одиночную кавычку в пользовательском интерфейсе: 17: 34: 40,927 ERROR JDBCExceptionReporter: 101 - У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с порядком «%» от BaseBookingInfoTO.bookingDateGMT desc 'по строке 1 17: 34: 40,929 ОШИБКА AbstractEntityManagerImpl: 580 - Невозможно отметить откат для PersistenceException: java.lang.IllegalStateException: no transaction st ... – Chailie

0

Вы должны использовать переменные привязки в вашем SQL заявление. Как уже упоминалось, это делается с помощью PreparedStatements в Java.

Чтобы убедиться, используются только допустимые имена столбцов, вы можете проверить ввод данных по базе данных. MySQL предоставляет информацию о схеме, такую ​​как столбцы каждой таблицы, как часть INFORMATION_SCHEMA. Для получения более подробной информации, обратитесь к документации MySQL:

"The INFORMATION_SCHEMA COLUMNS Table"

+0

Спасибо за ваш ответ, но в моем случае инструкция SQL динамически собрана. Так что боюсь, я не могу использовать PreparedStatement direct – Chailie

Смежные вопросы