java代码审计之sql注入

检查点:数据库查询

前言:

在 Java 中,操作SQL的主要有以下几种方式:

  1. java.sql.Statement

  2. java.sql.PrepareStatement

  3. 使用第三方 ORM 框架 —— MyBatis 或 Hibernate

下面我们来分析以上几种执行SQL的方式。

 

java.sql.Statement

java.sql.Statement 是最原始的执行SQL的接口,使用它时,需要手动拼接SQL语句,如下面这样:

java代码审计之sql注入_第1张图片

构造请求 /?id='or 1 #,服务器将 'or 1 # 拼接到 sql 语句中,就会变成 SELECT * FROM user WHERE username = ''or 1 #,将返回 user 表的所有记录。故不推荐此写法。java代码审计之sql注入_第2张图片

 

java.sql.PrepareStatement

这个接口是对 java.sql.Statement 的拓展,拥有了防SQL注入的特性。

Tip: java.sql.Statement 每次执行一条SQL,都要重新编译一次SQL。而 java.sql.PreparedStatement 预编译的方式,会将SQL缓存在数据库,可以重复调用,相比 Statement 效率要高一些。

使用时,在SQL语句中, ? 作为占位符,代替需要传入的参数,然后将该语句传递给数据库,数据库会对这条语句进行预编译。如果要执行这条SQL,只要用特定的 set 方法,将传入的参数设置到SQL语句中的指定位置,然后调用 execute 方法执行这条完整的SQL,也就是参数化查询语句。以javasec示例如下:

java代码审计之sql注入_第3张图片

预处理的修复原理:针对字符串类型的SQL注入,是在字符串两边加上一对单引号'',对于中间点的单引号对其进行转义\'

java代码审计之sql注入_第4张图片

Mybatis的#{}也是预处理方式处理SQL注入。

#{} 相当于JDBC中的PreparedStatement,预编译处理参数,可有效避免注入 
${} 直接拼接sql语句,若使用不当可造成SQL注入

此时,如果我用之前的请求攻击,执行的SQL会变成 SELECT * FROM user WHERE username = '\'or 1 #',可以看到单引号是被转义了,同时参数也被一对单引号包裹,数字型注入也不存在了。

处理方法:

1、所以对于sql注入采用预编译即可。参数化查询。

2、对于mybatis则可添加全局过滤器,过滤特殊字符。

Web.xml:

java代码审计之sql注入_第5张图片

SQLFilter.java中:

3、修改数据类型

变量 id的数据类型是 string 型,而其实对于这个用户信息查询的功能来说,只需要一个整数型的数字即可,因此可以修改变量 id 的数据类型,来达到修复的目的: 当然,这种方法只限定于特定情况下,如果有的参数其数据类型必须为 String 那么这种方法是行不通的。

如 Mybatis 框架中的 like、 in和 order by 语句、Hibernate 框架中的 createQuery()函数等,如果使用不当,依旧可能造成 sql 注入。

补充:

Mybatis的#{}也是预处理方式处理SQL注入。

在使用了mybatis框架后,需要进行排序功能时,在mapper.xml文件中(mybatis中Mapper映射文件)编写SQL语句时,注意orderBy后的变量要使用${},而不用#{}

因为#{}变量是经过预编译的,

${}没有经过预编译。

虽然${}存在SQL注入的风险,但orderBy必须使用${}因为#{}会多出单引号''导致SQL语句失效。为防止SQL注入只能自己对其过滤。 一些能防御SQL 注入的 API。

根据下面的结果可以发现order by 'username'并没有用,第一条SQL和第二条SQL效果一样。

select * from users order by 'username' desc -- 结果为 joychou wilson lightless,并没有用

select * from users                          -- 结果为 joychou wilson lightless 

select * from users order by username        -- 结果为 joychou lightless wilson

select * from users order by username desc   -- 结果为 wilson lightless joychou

java代码审计之sql注入_第6张图片

实际案例分析(CVE-2019-9615):待完善

 

相关文章:

   Java代码审计汇总系列(一)——SQL注入

参考链接:

从1开始的Java代码审计·第三弹·SQL注入

园长的github关于sql-inject

补充链接:

Mybatis中mapper映射文件详解

Mybatis中mapper映射文件中的#{}与${}

 
 
 
 
 

你可能感兴趣的:(java代码审计)