Я пишу этот вопрос, потому что я не нашел никакой полезной статьи о том, как предотвратить SQL-инъекцию в Spring Data JPA.Все учебные пособия показывают, как использовать эти запросы, но они ничего не упоминали об этих возможных атаках.
У меня следующий запрос:
@Repository
public interface UserRepository extends CrudRepository<User, Integer> {
@Query(nativeQuery = true, value = "SELECT * FROM users WHERE email LIKE %:emailAddress%")
public ResponseList<User> getUsers(@Param("emailAddress") String emailAddress);
}
Остальной контроллер для доставкизапрос:
@RequestMapping(value = "/get-users", method = RequestMethod.POST)
public Response<StringResponse> getUsers(WebRequest request) {
return userService.getUsers(request.getParameter("email"));
}
Перед тем, как выполнять их, экранируются JPQL или собственные параметры запроса?
Это запрос с внедрением SQL, выполненный в моей консоли MySQL, который удаляет таблицу пользователей:
SELECT * FROM users WHERE email LIKE '%'; DROP TABLE users; -- %';
Я попытался выполнить атаку SQL, отправив POST-запрос на сервер:
http://localhost:8080/get-users
POST: key/value: "email" : "'; DROP TABLE users; --"
Я включил ведение журнала Hibernate в sql, и вот что выдал приведенный выше запрос:
[http-nio-8080-exec-8] DEBUG org.hibernate.SQL - SELECT * FROM users WHERE email LIKE ?
Hibernate: SELECT * FROM users WHERE email LIKE ?
[http-nio-8080-exec-8] DEBUG org.hibernate.loader.Loader - bindNamedParameters() %'; DROP TABLE users; -- % -> emailAddress [1]
[http-nio-8080-exec-8] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%'; DROP TABLE users; -- %]
Таблица не была удалена (что хорошо), но почему параметр не экранирован?
Что если я не аннотирую @Param("emailAddress")
и использую индексированные параметры ?:
@Query(nativeQuery = true, value = "SELECT * FROM users WHERE email LIKE ?1")
public ResponseList<User> getUsers(String email);