安云网 - AnYun.ORG | 专注于网络信息收集、网络数据分享、网络安全研究、网络各种猎奇八卦。
当前位置: 安云网 > 技术关注 > 网络安全 > 审计mybatis的SQL注入

审计mybatis的SQL注入

时间:2017-06-02来源:未知 作者:安云网点击:
mybatis 概述 MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Ol

mybatis 概述

MyBatis是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录 //本文来自安云网

mybatis存在的sql注入问题

mybatis避免了用户直接拼接SQL语句,但是认为只要使用了mybatis就可以杜绝SQL注入的观点是不正确的。mybatis在配置SQL语句的时候,有两种描述参数的方式。#{}和${}。

//安云网咨询系统

比如:

//ANYUN.ORG

//内容来自AnYun.ORG

1

//内容来自安云网

<select id="selectPerson" parameterType="int" resultType="hashmap"> SELECT * FROM PERSON WHERE ID = #{id} </select>

//安云网,anyun.org

  //安云网咨询系统

这个语句被称作 selectPerson,接受一个 int(或 Integer)类型的参数,并返回一个 HashMap类型的对象,其中的键是列名,值便是结果行中的对应值。 //copyright AnYun.ORG

注意参数符号:

//内容来自AnYun.ORG

//内容来自安云网

1

//本文来自安云网

#{id}

//内容来自AnYun.ORG

  //安云网,anyun.org

这就告诉 MyBatis 创建一个预处理语句参数,通过 JDBC,这样的一个参数在 SQL中会由一个“?”来标识,并被传递到一个新的预处理语句中,就像这样: //本文来自安云网

//copyright AnYun.ORG

1 //copyright AnYun.ORG

// Similar JDBC code, NOT MyBatis… String selectPerson = "SELECT * FROM PERSON WHERE ID=?"; PreparedStatement ps = conn.prepareStatement(selectPerson); ps.setInt(1,id); //安云网,anyun.org

  //copyright AnYun.ORG

使用#mybatis会使用预编译来处理参数,这样子可以避免SQL注入。 //copyright AnYun.ORG

但是使用$描述参数会直接把变量拼接到SQL语句中,不做任何处理。相当于直接字符串拼接SQL。这样的方式就可能存在SQL注入。下面的描述来自mybatis官方文档。 //本文来自安云网

默认情况下,使用#{}格式的语法会导致 MyBatis 创建预处理语句属性并安全地设置值(比如?)。这样做更安全,更迅速,通常也是首选做法,不过有时你只是想直接在 SQL 语句中插入一个不改变的字符串。比如,像 ORDER BY,你可以这样来使用: ORDER BY ${columnName} 这里 MyBatis 不会修改或转义字符串。 NOTE 以这种方式接受从用户输出的内容并提供给语句中不变的字符串是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。 //ANYUN.ORG

demo演示 //ANYUN.ORG

使用MyBatis使用示例作为demo测试。 //安云网,anyun.org

mapper文件:

//ANYUN.ORG

//内容来自安云网

//内容来自AnYun.ORG

1 //安云网咨询系统

2

//内容来自安云网

3 //ANYUN.ORG

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper //安云网,anyun.org

        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

//copyright AnYun.ORG

        "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="test.mybatis.UserMapper"> <!-- 这里namespace必须是UserMapper接口的路径” --> <insert id="insertUser" parameterType="User"> insert into user(name,age) values(#{name},#{age}) <!-- 这里sql结尾不能加分号,否则报“ORA-00911”的错误 --> </insert> <!-- 这里的id必须和UserMapper接口中的接口方法名相同 --> <select id="getUser" resultType="User"> select * from user where name=#{name} </select> </mapper> //安云网咨询系统

 

//ANYUN.ORG

在输入中插入单引号 //安云网咨询系统

//内容来自安云网

1

//安云网咨询系统

2

//ANYUN.ORG

3 //内容来自安云网

4 //内容来自AnYun.ORG

5 //copyright AnYun.ORG

6

//安云网咨询系统

7 //安云网,anyun.org

8 //本文来自安云网

public static void getUser() { //内容来自安云网

    SqlSession sqlSession = sqlSessionFactory.openSession(); try { //安云网咨询系统

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

//copyright AnYun.ORG

        User user = userMapper.getUser("'zhangsan"); //安云网咨询系统

        System.out.println("name: " + user.getName() + "|age: " + user.getAge()); //本文来自安云网

    } finally { //内容来自安云网

        sqlSession.close(); //copyright AnYun.ORG

    } //copyright AnYun.ORG

 

//ANYUN.ORG

查看执行的sql语句:

//内容来自AnYun.ORG

审计mybatis的SQL注入-安全盒子 //内容来自AnYun.ORG

可以看到输入被单引号包裹,并且对字符串中的单引号进行了转义。

//内容来自AnYun.ORG

将#改成$,mapper文件为:

//安云网,anyun.org

//本文来自安云网

1

//安云网咨询系统

2

//内容来自AnYun.ORG

<select id="getUser" resultType="User"> select * from user where name=${_parameter}

//内容来自AnYun.ORG

</select>

//内容来自安云网

  //本文来自安云网

这里由于代码的写法问题,name需要改成_parameter,参考Mybatis中传参包There is no getter for property named XXX in class java.lang.String//内容来自安云网

查看执行的SQL语句:

//copyright AnYun.ORG

审计mybatis的SQL注入-安全盒子 //内容来自安云网

输入没有任何改变的拼接到SQL中,造成了SQL注入。 //copyright AnYun.ORG

实战分析

mybatis generator插件默认生成的order by 条件是使用$表示变量。 //内容来自安云网

//本文来自安云网

1 //安云网,anyun.org

... <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.tgwoo.ctspmt.model.MtVMsgItemExample" > <include refid="OracleDialectPrefix" /> select <if test="distinct" > distinct </if> <include refid="Base_Column_List" /> from CTSPMT.MT_V_MSG_ITEM <if test="_parameter != null" > <include refid="Example_Where_Clause" /> </if> <if test="orderByClause != null" > order by ${orderByClause} </if> <include refid="OracleDialectSuffix" /> </select> ... <sql id="OracleDialectPrefix" > <if test="page != null" > select * from ( select row_.*, rownum rownum_ from ( </if> </sql> <sql id="OracleDialectSuffix" > <if test="page != null" > <![CDATA[ ) row_ ) where rownum_ > #{page.begin} and rownum_ <= #{page.end} ]]> </if> </sql> ...

//copyright AnYun.ORG

 

//copyright AnYun.ORG

所以使用mybatis generator插件生成的代码中,需要自己过滤order by参数,如果用户可控就会导致SQL注入。而大部分情况下,开发者可能没有意识到这个问题。

//内容来自安云网

以freecms为例。Freecms是一款开源javacms。最新版下载地址。freecms中的orderby都是使用的$描述变量。

//内容来自安云网

审计mybatis的SQL注入-安全盒子

//内容来自AnYun.ORG

前面的分析可以知道,这种情况,mybatis会直接拼接字符串到SQL中不做任何处理。 //ANYUN.ORG

注册用户登录访问:

//安云网,anyun.org

//本文来自安云网

1 //copyright AnYun.ORG

http://192.168.99.100:8080/freecms/member/creditlog_list.do?order=extractvalue(1,concat(0x7C,(select%20user()),0x7C))

//安云网,anyun.org

 

//本文来自安云网

审计mybatis的SQL注入-安全盒子 //安云网,anyun.org

查看执行的SQL为: //内容来自安云网

审计mybatis的SQL注入-安全盒子

//安云网咨询系统

修复方案

尽量使用#描述参数,如果一定要使用$,则需要自己过滤用户输入。

//安云网咨询系统

来自:xdxd//安云网咨询系统


//内容来自AnYun.ORG

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
验证码: 点击我更换图片
相关内容