3.jpg

微信公众号:爱问CTO
专业编程问答社区
www.askcto.com

1.先看#{}解析为一个JDBC预编译语句(prepared statement)的参数标记符,把参数部分用占位符 ? 代替。动态解析为:

select * from t_user where username = ?;

而传入的参数将会经过PreparedStatement方法的强制类型检查和安全检查等处理,最后作为一个合法的字符串传入。

在#{}预处理之后可以预防SQL注入传入username 为 a‘or’1=1,使用#{},经过sql动态解析和预编译,会把单引号转义为 ’ 那么sql最终解析为:

select * from t_user where username = "a\' or \'1=1 ";

2.再看${}这种方式只会做简单的字符串替换,在动态SQL解析阶段将会进行变量替换,假如传递的参数为51mn,最终处理结果如下:

select * from t_user where username = '51mn' ;

${} 预编译之前就已经被替换,有被注入的风险。如果传入的username 为 a‘or’1=1,那么使用 ${} 处理后直接替换字符串的sql就解析为:

select * from t_user where username = 'a' or '1=1' ;

所有的用户信息都会被查询出来了。


爱问CTO
18 声望2 粉丝

爱问CTO 专业编程问答网站