上周六单位被扫描出SQL注入漏洞 经过检查,发现ibatis框架都可能出现这个问题.
如果有需求,让你实现页面grid所有字段都能排序,你会怎么做呢? 最简单的做法就是从页面把字段名,排序类型传回来,然后拼接在SQL里面.(在使用EasyUI前端框架的时候,这样做非常容易) 然后修改ibatis框架,将order by #排序字段# #排序类型#改为 order by $排序字段$ $排序类型$ 实现所谓的动态查询,就像下面的链接所写的 http://blog.sina.com.cn/s/blog_4dacfb0101016y6b.html
实验模拟这个过程, create table t (id int primary key ,name varchar(20),grade int); insert into t values(1,'edmond',1); insert into t values(2,'edmond',2); insert into t values(3,'edmond',1); insert into t values(4,'edmond',3); insert into t values(5,'edmond',1); insert into t values(6,'edmond',5);

  1. public class Test {
  2. private static String URL = "jdbc:mysql://127.0.0.1:3306/mvbox";
  3. private static String USERNAME = "xx";
  4. private static String PWD = "xx";
  5. public static void main(String[] args) throws Exception {
  6. //模拟从页面传输过来的参数
  7. String name = "edmond";
  8. String sort = "grade";
  9. String order = "desc";
  10. dao(name, sort, order);
  11. }
  12. private static void dao(String name, String sort, String order) throws Exception {
  13. Class.forName("com.mysql.jdbc.Driver");
  14. Connection con = DriverManager.getConnection(URL, USERNAME, PWD);
  15. PreparedStatement ps = con.prepareStatement("select id,name,grade from t where name=? order by " + sort + " " + order);
  16. ps.setString(1, name);
  17. ResultSet rs = ps.executeQuery();
  18. while (rs.next()) {
  19. System.out.println(rs.getInt(1) + "\t" + rs.getString(2) + "\t" + rs.getInt(3));
  20. }
  21. con.close();
  22. }
  23. }

上面的代码模拟了ibatis使用$符号实现动态排序查询的场景.运行结果如下 可以看到上述代码存在注入漏洞 如果对参数order注入如下内容,即可以作为暴力攻破帐号密码的方式,又可以使用sleep挂起数据库. String order = "desc,(select if(substring(user(),1,2)='xx',sleep(4),-1))";
攻击方式参考: http://www.jxcm.net/shujuku/64.html
如何避免注入攻击,并且用ibatis实现动态排序查询呢? 我感觉可以使用受控注入的方式.(自己想的一个名词) 在监听器中获取数据库所有的列名称,然后使用AOP拦截DAO层的方法, 将前台传入的参数,对比监听器中获取的数据库列名称,如果没有任何匹配,则直接报错,或者给一个默认的排序 ibatis的SQL还是使用$符号的方式.
模拟代码如下

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. public class Test {
  9. private static String URL = "jdbc:mysql://127.0.0.1:3306/mvbox";
  10. private static String USERNAME = "xx";
  11. private static String PWD = "xx";
  12. private static List<String> fieldList = new ArrayList<String>();
  13. private static void getAllField() throws Exception {
  14. Class.forName("com.mysql.jdbc.Driver");
  15. Connection con = DriverManager.getConnection(URL, USERNAME, PWD);
  16. PreparedStatement ps = con
  17. .prepareStatement("select column_name from information_schema.columns where table_schema not in ('information_schema','test','mysql','information_schema')");
  18. ResultSet rs = ps.executeQuery();
  19. while (rs.next()) {
  20. fieldList.add(rs.getString(1));
  21. }
  22. rs.close();
  23. ps.close();
  24. con.close();
  25. }
  26. public static void main(String[] args) throws Exception {
  27. // 模拟监听器启动
  28. getAllField();
  29. // 模拟从页面传输过来的参数
  30. String name = "edmond";
  31. String sort = "grade";
  32. String order ="desc,(select if(substring(user(),1,2)='xx',sleep(4),-1))";
  33.         daoProxy(name, sort, order);
  34. }
  35. private static void daoProxy(String name, String sort, String order)
  36. throws Exception {
  37. if (fieldList.contains(sort)
  38. && (order.toLowerCase().equals("desc") || order.toLowerCase()
  39. .equals("asc"))) {
  40. dao(name, sort, order);
  41. } else {
  42. // 记录日志,进行错误处理
  43. System.out.println("黑客,你妈妈喊你回家吃饭");
  44. }
  45. }
  46. private static void dao(String name, String sort, String order)
  47. throws Exception {
  48. Class.forName("com.mysql.jdbc.Driver");
  49. Connection con = DriverManager.getConnection(URL, USERNAME, PWD);
  50. PreparedStatement ps = con
  51. .prepareStatement("select id,name,grade from t where name=? order by "
  52. + sort + " " + order);
  53. ps.setString(1, name);
  54. ResultSet rs = ps.executeQuery();
  55. while (rs.next()) {
  56. System.out.println(rs.getInt(1) + "\t" + rs.getString(2) + "\t"
  57. + rs.getInt(3));
  58. }
  59. con.close();
  60. }
  61. }

可以看到,在DAO层拦截之后,在daoProxy中已经过滤了注入攻击. 这样即可以保证安全,又可以让代码优雅.

ibatis Order By注入问题的更多相关文章

  1. IBatis.Net使用总结(一)-- IBatis解决SQL注入(#与$的区别)

    IBatis解决SQL注入(#与$的区别) 在IBatis中,我们使用SqlMap进行Sql查询时,需要引用参数,在参数引用中可以使用两种占位符#和$.这两种占位符有什么区别呢? (1):#***#, ...

  2. mysql的order by注入

    最近在做一些漏洞盒子后台项目的总结,在盒子众多众测项目中,注入类的漏洞占比一直较大.其中Order By注入型的漏洞也占挺大一部分比例,这类漏洞也是白帽子乐意提交的类型(奖金高.被过滤概览小).今天给 ...

  3. Mysql Order By注入总结

    何为order by 注入 本文讨论的内容指可控制的位置在order by子句后,如下order参数可控"select * from goods order by $_GET['order' ...

  4. order by注入点利用方式分析

    漏洞分析 使用sqli-lab中的lesson-52作为测试目标.关键代码为: error_reporting(0); $id=$_GET['sort']; if(isset($id)) { //lo ...

  5. Mysql Order By 注入总结

    前言 最近在做一些漏洞盒子后台项目的总结,在盒子多期众测项目中,发现注入类的漏洞占比较大.其中Order By注入型的漏洞也占挺大一部分比例,这类漏洞也是白帽子乐意提交的类型(奖金高.被过滤概率小). ...

  6. order by 注入姿势

    order by 注入原理 其实orde by 注入也是sql注入的一种,原理都一样就是mysql语法的区别,order by是用来排序的语法. sql-lab讲解 判断方法 1.通过做运算来判断如: ...

  7. ThinkPHP3.2.4 order方法注入

    漏洞详情: 漏洞文件:./ThinkPHP\Library\Think\Db\Driver.class.php 中的 parseOrder方法: 这也是继上次order方法注入之后的修复手段. 可以看 ...

  8. ibatis order by 防止sql注入

    (1) 排序控制 select TABLE_NAME, TABLESPACE_NAME from user_tables order by TABLE_NAME $ordertype$ Where t ...

  9. iBatis的SQL注入

    sqlMap中尽量不要使用$;$使用的是Statement(拼接字符串),会出现注入问题.#使用的是PreparedStatement(类似于预编译),将转义交给了数据库,不会出现注入问题:.前者容易 ...

随机推荐

  1. .net将List序列转为Json字符串

    将List类型转化为Json,是我们平常开发时最常见的了.在使用中,有很多种方法,也可以使用. 第一种 第三方组件:Newtonsoft.Json.dll //转化成Json Newtonsoft.J ...

  2. lua-redis-parser module

    https://github.com/openresty/lua-redis-parser 此模块主要是处理redis请求和响应的. local parser = require "redi ...

  3. Part 1: Setting up ARM GNU tool chain

    ARM Build Tools GNU Tools for ARM Embedded Processors. GNU Make for Windows. GNU Tools for ARM Embed ...

  4. proxy的作用

    get() get方法用于拦截某个属性的读取操作,可以接受三个参数,依次为目标对象.属性名和 proxy 实例本身(严格地说,是操作行为所针对的对象),其中最后一个参数可选. get方法的用法,上文已 ...

  5. git提交过程中遇到的 index.lock 问题导致无法提交的解决方法

    在提交代码的过程中,可能会遇到下面的问题: fatal: Unable to create 'C:/programLists/zzw-q1/.git/index.lock': File exists. ...

  6. JavaScript数组forEach循环

    JavaScript数组forEach循环 今天写JavaScript代码把forEach循环数组忘记写法了,在此记录一下以防止未来忘记. let a = [1, 2, 3]; a.forEach(f ...

  7. MySQL获取字段的片段

    如表中有很多这样的数据: TEST-123,TEST-III 这种以 TEST开头的数据,为了统计其总数 可以使用mysql自带的方法 substring_index()方法 第一个参数是列的内容, ...

  8. Mybatis Dao开发的两种方式(一)

     原始Dao的开发方式: 1.创建数据库配置文件db.properties jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localh ...

  9. python中文分词工具——结巴分词

    传送门: http://www.iteye.com/news/26184-jieba

  10. Expression Blend实例中文教程(4) - 布局控件快速入门Canvas

    上一篇,我介绍了Silverlight控件被分为三种类型, 第一类: Layout Controls(布局控件) 第二类: Item Controls (项目控件) 第三类: User Interac ...