spring-boot - 防止JPQL查询sql注入
问题描述
我被告知以下查询不安全,因为来自前端输入字段的参数: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)。不确定这是否仍然不安全。
解决方案
我被告知以下查询作为参数不安全:searchFor
你应该质疑这个建议。
当客户端传递的参数值可能会传输额外的查询逻辑(通常是不希望的)并且在执行的查询中将被允许时,就会发生 SQL 注入。
例如,参数值可以在查询中包含附加逻辑,而不是简单的foo
文本值 searchFor
,例如:foo OR ''=''
。那就是SQL注入。
在您的情况下,SQL 注入是不可能的,因为您没有手动设置参数,而是依靠一种安全的方式来绑定searchFor
参数:Spring。
实际上,Spring 像 JPA 实现一样以安全的方式绑定参数值,即从 JPA Query 实例设置参数值,该实例可防止声明参数的 SQL 注入。
例如采取这个查询(我删除了%
简化的部分):
"SELECT u FROM User u WHERE lower(u.username) LIKE :searchFor"
并尝试searchFor
使用 String设置参数"foo OR ''==''"
以尝试注入始终为 true 的 SQL 条件。
如果您打开 JPA 实现的日志以输出参数绑定(对于 Hibernate : logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
),您可能会看到如下内容:
TRACE 11012 --- [nio-8080-exec-8] ohtype.descriptor.sql.BasicBinder:绑定参数 [1] 作为 [VARCHAR] - [foo OR ''=='']
绑定 仅针对参数值执行,而不是作为添加新查询逻辑的一种方式。受保护的最终查询部分受到以下保护:
SELECT u FROM User u WHERE lower(u.username) LIKE "foo OR ''==''"
推荐阅读
- c# - 获取枚举名称
- django - Django 2.1 TypeError: __init__() 得到了一个意外的关键字参数“on_delete”
- javascript - __doPostBack 未在 chrome 浏览器中触发。在 IE 中工作
- android - 菜单未显示在片段中
- android - 如何操作后退按钮?
- javascript - 如何知道 Web Worker 何时加载失败?
- angular - Angular 6、节点、护照和 OAuth2
- mysql - 案例在 Phalcon 模型管理器中的使用没有给出正确的值
- java - 使用 vert.x 处理异步操作
- php - 一次提交插入多个表