Java Spring JPA 本机查询 SQL 注入证明?
Is Java Spring JPA native query SQL injection proof?
我写这个问题是因为我没有找到任何关于如何在 Spring Data JPA 中防止 SQL 注入的有用文章。所有的教程都在展示如何使用这些查询,但他们没有提到任何关于这些可能的攻击。
我有以下查询:
@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 或本机查询参数在执行之前是否进行了转义?
这是在我的 MySQL 控制台中执行的带有 SQL 注入的查询,它删除了用户 table:
SELECT * FROM users WHERE email LIKE '%'; DROP TABLE users; -- %';
我试图通过向服务器发送 POST 请求来执行 SQL 攻击:
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; -- %]
table 没有被丢弃(这很好)但是为什么参数没有被转义?
如果我不注释 @Param("emailAddress")
并使用索引参数怎么办?:
@Query(nativeQuery = true, value = "SELECT * FROM users WHERE email LIKE ?1")
public ResponseList<User> getUsers(String email);
Spring Data JPA 的所有功能都使用绑定参数。进行的字符串连接很少,而且只有不是来自最终用户的东西。
因此 Spring Data JPA 可以安全地防止 SQL 注入。
What if I don't annotate the @Param("emailAddress") and I use indexed parameters?
这与您使用索引参数或命名参数无关。
why the parameter isn't escaped?
由于绑定参数值不是 SQL 语句的一部分,该语句被解析并转换为数据库中的执行计划,因此无需对参数进行转义。确实这样做是错误的。
我写这个问题是因为我没有找到任何关于如何在 Spring Data JPA 中防止 SQL 注入的有用文章。所有的教程都在展示如何使用这些查询,但他们没有提到任何关于这些可能的攻击。
我有以下查询:
@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 或本机查询参数在执行之前是否进行了转义?
这是在我的 MySQL 控制台中执行的带有 SQL 注入的查询,它删除了用户 table:
SELECT * FROM users WHERE email LIKE '%'; DROP TABLE users; -- %';
我试图通过向服务器发送 POST 请求来执行 SQL 攻击:
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; -- %]
table 没有被丢弃(这很好)但是为什么参数没有被转义?
如果我不注释 @Param("emailAddress")
并使用索引参数怎么办?:
@Query(nativeQuery = true, value = "SELECT * FROM users WHERE email LIKE ?1")
public ResponseList<User> getUsers(String email);
Spring Data JPA 的所有功能都使用绑定参数。进行的字符串连接很少,而且只有不是来自最终用户的东西。
因此 Spring Data JPA 可以安全地防止 SQL 注入。
What if I don't annotate the @Param("emailAddress") and I use indexed parameters?
这与您使用索引参数或命名参数无关。
why the parameter isn't escaped?
由于绑定参数值不是 SQL 语句的一部分,该语句被解析并转换为数据库中的执行计划,因此无需对参数进行转义。确实这样做是错误的。