上周六单位被扫描出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. vue过渡效果

    vue过渡效果. <transition name='slide-fade'> <div class="top" @click='gotoTop' v-if='s ...

  2. 使用group by rollup和group by cube后的辅助函数

    本文主要介绍,报表在使用group by rollup和group by cube后的辅助函数. CREATE TABLE TEST8 ( "ID" NUMBER, "O ...

  3. Linux du与df命令的差异

    今天上午查看磁盘空间,df命令查看的时候:93%,du命令查看的时候:90%.回想起昨天在用ftp传输过程中,rm掉文件,应该是文件虽然表明上删除掉了,但是空间实际是未释放的. 由于du与df命令实施 ...

  4. mvc框架的学习步骤

    1 搭建环境.有个感性认识 2 如何完成controller和viewer的映射 3 如何把值传给controller 4 controller如何把值传给view 5 异常处理 6 页面标签 7文件 ...

  5. 【Lua】linux下lua+mod_lwt环境搭建

    Lua 是一个小巧的脚本语言.它具有轻量级.可扩展等优势.它可以作为一个强大.轻量的脚本语言,供任何需要的程序使用. LWT (Lua Web Tools) 可让你使用 Lua 开发 Web 应用,并 ...

  6. C#使用System.xml.linq来生成XML文件

    直接看代码: /* * <?xml version="1.0" encoding="utf-8"?> * <Files Path=" ...

  7. idea tomcat添加

    https://blog.csdn.net/fanhenghui/article/details/69258499

  8. 九度oj 1006 ZOJ问题 2010年浙江大学计算机及软件工程研究生机试真题

    题目1006:ZOJ问题 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:16244 解决:2742 题目描述: 对给定的字符串(只包含'z','o','j'三种字符),判断他是否能AC.是 ...

  9. ExtJs6自定义scss解决actionColum中iconCls图标不能调样式的问题

    问题:图标样式不对,icon(本地图片)是对的,iconCls(引用的)样式不对 查ExtJs6的API里面说,可以用style添加样式,然而并没有作用 最后在该文件树下建立scss,最好和view文 ...

  10. Truncated incorrect DOUBLE value: 'NO_REFUND'

    解决办法:Mysql中,如果一个字段是字符串,则一定要加单引号 问题原因: `item_refund_state` ) NOT NULL item_refund_state字段的类型是varchar但 ...