前言: 前辈给的例子,我们进行分析
大纲
代码结合实际场景分析
- SQL注入 攻 击 只 对 Statement有效, 对 PreparedStatement 是无效的
1、 产生注入语句
- 核心代码
Statement statement = con.createStatement();
String sql = "select * from users where username = '" + username + "'";
System.out.println(sql);
ResultSet rs = statement.executeQuery(sql);
- 传入username = joychou’ or ‘a’='a 时候。结果为:
解决方法:使用PreparedStatement转义
针对于此种情况,我们需要对传入的字符串进行预处理
的方式。
原理:针对字符串类型的SQL注入:1\在字符串两边加上一对单号''
, 2、字符串两边的单音好进行转义 \'
,让字符变成单引号。Mybatis的#{ }
就是这样处理的。
- 传入username = joychou’ or ‘a’='a 时候。结果为:
- 此次改变不允许破坏逻辑结构
需手动解决的问题
- orderBy / like 后的变量要使用${},而不用#{}
- 没 有 经 过 预 编 译 。 虽 然 {}没有经过预编译。虽然 没有经过预编译。虽然{}存在SQL注入的风险,但orderBy必须使用${}
- 因为#{}会多出单引号’'导致SQL语句失效。为防止SQL注入只能
自己对其过滤
。
防止 %23出现问题
%23 经过url编译之后为#。
- 例如
<select id="findByUserNameVul2" parameterType="String" resultMap="User">
select * from users where username like '%${_parameter}%'
</select>
传入%joychou’ or ‘1’=‘1’ %23时。传入mysql为
以上的mysql注入类型知识整理了一点点,以后碰到了会及时进行补充。2021/11/30/4:33