ibatis[mybatis]的安全加固

对于mapping框架,其实预编译语句已经解决了绝大多数的sql注入。

但是对mapping如果支持动态语句,就和程序拚接一样存在sql注入的可能。所以在ibatis[mybatis]中,安全加固主要针对 $ 符号拚接的动态语句

select * from userinfo where name = {#name} oder by $orderColumn$  $sortMode$

这是一种非常典型的场景,因为可以按多种方式排序,所以orderColumn是动态传入的,同样sortMode也是动态传入的,这样的解释语句时除了

name = {#name} 可以确定为 name = ?这样的预编译语名,不存在sql注入的风险,orderColumn  和sortMode都有可能传入特殊变量构造成危险sql。

因为这两个变量字符串是动态拚接到语句上:

set  orderColumn = "name; delete from userinfo;";  构造成  select * from userinfo where name = ? oder by name;delete from userinfo; xxx

所以在加固时主要针对$进行拦截 。

在ibaties中,因为没有拦截器,主要是hack源码,重新打包,入口在SimpleDynamicSql类的getSql方法,这里我们获取原始的sql后,根据$对sql切分:

String[] tokens = sql.split(‘$‘);

我们要保证$xxx$中的变量一定是变量形式传给sql语句而不是和sql直接拚接,那个有两种方案,一时直接转换成字符串,比如:

DatabaseMetaData md = connection.getMetaData();
quote= md.getIdentifierQuoteString();

newSql.append(quote).append(paramter).(quote);

另一种如果是基础关键字就直接append, 如:

newSql.append("DESC");

这样就构成了:

select * from userinfo where name = ? oder by ‘name’ DESC;而不存在sql注入,把上面两种方法抽象成两种变量:

KEYWORD和METADATA

KEYWORD是只允许牧举的值,在写mapper的sql时必须以这种抽象形式,否则为空(sql出错比sql注入可靠):

select * from userinfo where name = {#name} oder by $orderColumn:METADATA$  $sortMode:KEYWORD$

这样对上面的String[] tokens就非常好处理了:

newSql = new StringBuider();

for(String tk:tokens){

String[] vk = tk.split(":");

if(vk.length == 1)    newSql.append(tk).append(" ");

else{

if("METADATA".equals(vk[1]))  newSql.append(tk).append(quote).append(pm)..append(quote).append(" ");//pm从ParameterObject中根据vk[0]的名称获取

else if("KEYWORD".equals(vk[1])) newSql.append(vk[0] from KEYWORD)..append(" ");

}

}

return newSql.toString();

对于mybatis,由于拦截器模式的作用,我们不必在源代码上hack了,只要加一个拦截器:

@Intercepts({@Signature(method = "prepare", type = StatementHandler.class, args = {Connection.class})})
public class MyInterceptor implements Interceptor {

public Object intercept(Invocation invocation) throws Throwable {
        BoundSql boundSql = xxx;
        String sql = boundSql.getSql();
        String newSql = xxx; //上面的方案
        ReflactHelper.setValueByFieldName(boundSql,”sql”,newSql);        
        return invocation.proceed();
    }
}

在conf中加上这个拦截器:

<configuration>
   <plugins>
      <plugin interceptor="package.MyInterceptor"></plugin>
   </plugins>
   <environments default="development">
      <environment id="development">
         <transactionManager type="JDBC" />
         <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver" />
            <property name="url" value="jdbc:mysql://localhost:3306/mysql" />
            <property name="username" value="username" />
            <property name="password" value="password" />
         </dataSource>
      </environment>
   </environments>
   <mappers>
      <mapper resource="mapper.xml" />
   </mappers>
</configuration>


版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-07 12:03:07

ibatis[mybatis]的安全加固的相关文章

ibatis/mybatis显示sql语句 log4j.properties配置文件

将ibatis/mybatis log4j运行级别调到DEBUG可以在控制台打印出ibatis运行的sql语句,方便调试: ### 设置Logger输出级别和输出目的地 ### log4j.rootLogger=debug,stdout,logfile ### 把日志信息输出到控制台 ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender #log4j.appender.stdout.Target=System.err log4j.a

JDBC、ibatis(mybatis)、Hibernate有什么不同?

①JDBC编程流程固定,同时将sql语句和java代码混在了一起,经常需要拼凑sql语句,细节很繁琐: ②ibatis(mybatis)它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象.但是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大. ③H

ibatis mybatis传入List参数

--ibatis <select id="getWzlb" parameterClass="map" resultClass="java.util.HashMap"> select ... from wz09 where 1=1 <isNotEmpty prepend="AND" property="ids"> <!-- ids是map的一个key --> id in &

JPA,Hibernate,ibatis(mybatis)如何选用?

转自:http://t.51jdy.cn/thread-259-1-1.html 传统的 业务系统,通常业务都比较复杂,懂业务的运维人员 对sql查询工具都比较熟悉.这种以 数据库 为主的 业务场景 使用 以sql为主的持久层框架 例如:ibatis,mybatis这种 性能优化的时候 sql 语句调整较为方便,甚至 业务人员 会直接提供 业务对于的 sql给开发人员. 对于快速迭代的中小型 新项目,适合使用hibernate(JPA + hibernate驱动).快速迭代 适合 使用面向对象的

SqlMapConfig.xml中的setting属性 Ibatis mybatis

<settingscacheModelsEnabled="true"lazyLoadingEnabled="false"enhancementEnabled="true"maxSessions="64"maxTransactions="8"maxRequests="128"useStatementNamespaces="false"classInfoCacheE

ibatis (mybatis) for循环拼接语句

使用 , 拼接 查询条件dto public class queryCondition{ private String[] stuIds; private String name;} 查询sqlMap <select id="selectStu" parameterClass="cn.xy.queryCondition" resultClass="cn.xy.Student"> select id,name from student 

凤凰涅槃:从 iBatis 到 MyBatis

从 iBatis 到 MyBatis,你准备好了吗? 对于从事 Java EE 的开发人员来说,iBatis 是一个再熟悉不过的持久层框架了,在 Hibernate.JPA 这样的一站式对象 / 关系映射(O/R Mapping)解决方案盛行之前,iBaits 基本是持久层框架的不二选择.即使在持久层框架层出不穷的今天,iBatis 凭借着易学易用.轻巧灵活等特点,也仍然拥有一席之地.尤其对于擅长 SQL 的开发人员来说,iBatis 对 SQL 和存储过程的直接支持能够让他们在获得 iBati

Mybatis笔记三:iBatis与MyBatis区别

转载:http://www.tuicool.com/articles/auaAru iBatis 框架的主要优势: 1.iBatis 封装了绝大多数的 JDBC 样板代码,使得开发者只需关注 SQL 本身,而不需要花费精力去处理例如注册驱动,创建 Connection,以及确保关闭 Connection 这样繁杂的代码. 2.从 iBatis 到 MyBatis,不只是名称上的变化,MyBatis 提供了更为强大的功能,同时并没有损失其易用性,相反,在很多地方都借助于 JDK 的泛型和注解特性进

iBatis 和MyBatis区别

从  iBatis  到  MyBatis ,你准备好了吗? 对于从事 Java EE 的开发人员来说,iBatis 是一个再熟悉不过的持久层框架了,在 Hibernate.JPA 这样的一站式对象 / 关系映射(O/R Mapping)解决方案盛行之前,iBaits 基本是持久层框架的不二选择.即使在持久层框架层出不穷的今天,iBatis 凭借着易学易用.轻巧灵活等特点,也仍然拥有一席之地.尤其对于擅长 SQL 的开发人员来说,iBatis 对 SQL 和存储过程的直接支持能够让他们在获得 i