Предотвратить JPQL запрос SQL инъекций - PullRequest
1 голос
/ 08 марта 2019

Мне сообщили, что приведенный ниже запрос небезопасен, так как параметр : searchFor , поступающий из поля ввода в переднем конце, может использоваться для внедрения SQL. Пожалуйста, посоветуйте, что является лучшим решением для предотвращения внедрения SQL в приведенном ниже коде?

@Query("SELECT u FROM User u WHERE lower(u.username) LIKE %:searchFor% " +
        " OR lower(concat(u.firstname, ' ', u.lastname)) LIKE %:searchFor% " +
        " OR lower(u.email) LIKE %:searchFor%")
Page<User> findAllAndSearch(@Param(value = "searchFor") String searchFor, Pageable pageable);

Я не использую "+" для объединения строк, но вместо этого предоставляю параметр (: searchFor). Не уверен, что это все еще небезопасно.

Ответы [ 2 ]

2 голосов
/ 08 марта 2019

Вы должны оспорить это требование.

Внедрение SQL происходит, когда у вас нет гарантии, что значение параметра не будет защищено / проверено на предмет его структуры, которая может содержать не только значение «нормальное / ожидаемое» для параметра.
Например, вместо простого foo текстового значения для searchFor оно может содержать дополнительную логику в запросе foo OR ''=''.
Здесь это не должно быть возможно.
searchFor, указанное как @Param, не будет разрешено использовать при атаках SQL-инъекций. Spring будет привязывать значение параметра безопасным способом, как это делают реализации JPA, то есть устанавливает параметр из экземпляра запроса JPA, который защищен от SQL-инъекций для объявленных параметров.

Например, возьмем этот запрос (для упрощения я удалил часть %):

"SELECT u FROM User u WHERE lower(u.username) LIKE :searchFor"

И попробуйте установить параметр searchFor с помощью строки "foo OR ''==''", чтобы попытаться ввести условие SQL, которое всегда выполняется.
Если вы включите журнал реализации JPA для вывода привязки параметров (для Hibernate: logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE), вы можете увидеть что-то вроде:

TRACE 11012 --- [nio-8080-exec-8] o.h.type.descriptor.sql.BasicBinder : параметр привязки [1] как [VARCHAR] - [foo OR '' == '']

Привязка только выполняется для значения параметра, а не для добавления новой логики запроса. Последняя защищенная часть запроса защищена так:

SELECT u FROM User u WHERE lower(u.username) LIKE "foo OR ''==''"
1 голос
/ 08 марта 2019

Я полагаю, что базовая структура ORM очистит входные данные, если этот параметр будет передан в качестве параметра.

...