【SpringBoot】持久层 sql 注入问题

目录

概述

[#{} 与 {}](#{} 与 {})


概述

前端恶意传参,改变后端 sql 语句的语法结构,从而使后端给前端返回一些私密的数据。这种安全问题往往是因为没有严格过滤参数,或者后端代码不严谨导致的。

#{} 与 ${}

在 MyBatis 框架中,#{} 与 ${} 都表示占位符,方便灵活传参。如下代码

java 复制代码
@Select("select * from user_info where username= #{name} ")
UserInfo queryByName(String name);

#{} 使用的是 预编译 sql , ${} 使用的是 及时 sql 。

及时 sql :sql 语句要先经过 词法分析,语法分析,语义分析,再把优化后的 sql 喂给数据库执行。

也就是说,${} 占位符传过来的参数是要参与 sql 语法构建的,如果参数中带有一些 sql 的关键字,会在词法分析时被识别成 sql 的关键字。

预编译 sql : 会把编译好的 sql 缓存起来,当要使用该 sql 时,不会再进行 词法分析,语法分析,语义分析。

如此一来,不仅提高了 sql 的执行效率,#{} 传过来的参数不会参与 sql 的语法构建。

#{} 占位符会会根据类型,自动拼接 ' ' ,${} 会对参数直接进行替换,如果参数为字符串,需要加 ' ' 号。如下代码

java 复制代码
@Select("select * from user_info whereusername= '${name}' ")
UserInfo queryByName(String name);

因为 #{} 占位符会拼接 '' 号,在一些 sql 中,并不需要加单引号,就必须使用 ${} 占位符。如下示例

java 复制代码
@Select("select * from user_info order by id ${sort}")
public List<UserInfo> selectUserSortById(String sort);