2015-10-06 2 views
1

Я код, который переводит пользователя поисковое слово в запросе MySQL:Hibernate createSQLQuery - Как это проверить SQL?

String sql = String.format("SELECT * FROM my_table WHERE my_column = '%s'", value); 
HibernateUtil.getCurrentSession().createSQLQuery(sql); 

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

x'; DROP TABLE test;-- 

, что приводит к следующему запросу:

SELECT * FROM my_table WHERE my_column = 'x'; DROP TABLE test;-- 

Но Hibernate бросает SQLGrammarException. Когда я запускаю этот код через phpMyAdmin, он правильно выводит тестовую таблицу.

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

+0

Рекомендуется использовать параметризованные запросы. – doublesharp

+0

@ doublesharp, справа, но прежде чем я изменил весь код доступа к данным, мне захотелось проверить, что 'createSQLQuery' does * not * дезинформирует мой SQL. – gwg

+0

Что такое сообщение 'SQLGrammarException'? –

ответ

1

Вы можете быть уверены, что используете более чем в одном заявлении, поскольку createSQLQuery позволяет выполнить только одно заявление. Это не Hibernate, который защищает вас здесь, а ваш JDBC-драйвер соответственно вашей базы данных - потому что он не знает, как обрабатывать разделитель ; в контексте одного заявления.

Но вы все еще небезопасны для SQL-инъекций. В этом случае есть множество других возможностей для внедрения SQL. Только один пример:

Представьте, что вы ищете для некоторых конкретных пользовательских элементов в запросе:

String sql = String.format(
    "SELECT * FROM my_table WHERE userId = %s AND my_column = '%s'", 
    currentUserId, value); 

Теперь пользователь может ввести:

x' OR '1' = '1 

что приведет к SQL:

SELECT * FROM my_table WHERE userId = 1234 AND my_column = 'x' OR '1' = '1' 

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

Даже ваш предложенный пример может быть опасным, например

x' OR (SELECT userName FROM USER) = 'gwg 

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

1

В соответствии с Hibermate documentation метод createSQLQuery «Создайте новый экземпляр запроса для данной строки SQL», поэтому мы можем предположить, что Hibernate выполняет проверку SQL для одного запроса при каждом вызове этого метода.

Важно: createSQLQuery устарел в Hibernate, пожалуйста, ознакомьтесь с приведенной выше ссылкой, чтобы увидеть, как новые способы выполнения SQL-запросов выполняются.

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

This question имеет пример, в котором вы нуждаетесь, пожалуйста, проверьте его.

Надеюсь, это поможет вам в учебе, удачи!

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