上周六单位被扫描出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. SQL语句exists用法

    首先头脑中有三点概念: 1 .  EXISTS子查询找到的提交 NOT EXISTS 子查询中 找不到的提交 说明:不要去翻译为存在和不存在,把脑袋搞晕. 2 . 建立程序循环的概念,这是一个动态的查 ...

  2. 3dsmax2017卸载/安装失败/如何彻底卸载清除干净3dsmax2017注册表和文件的方法

    3dsmax2017提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装3dsmax2017失败提示3dsmax2017安装未完成,某些产品无法安装,也有时候想重新 ...

  3. 登陆界面背景动画的css样式

    为了达到更好的用户体验,登陆界面需要设计多张背景图进行动态切换 <!doctype html> <html lang="en"> <head> ...

  4. lucene关于IndexReader总结

    IndexReader.使用过程中有时会出现document被删除,reader还是原来的reader没有改变,所以使用openifchanged保证, 又因为IndexReader 初始化很耗费资源 ...

  5. MySQL获取字段的片段

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

  6. iconfont_3种引用方式

    IconFont 图标的3种引用方式   新版Iconfont-阿里巴巴矢量图标库支持三种引用方式: 1.unicode引用(原始) unicode是字体在网页端最原始的应用方式,特点是: 兼容性最好 ...

  7. vs2013中$(TargetPath)与Link.OutputFile不同,导致调试debug找不到exe

    之前把VS2008项目升级为VS2013项目后,出现了VS2013调试debug找不到exe文件的现象,如:http://blog.sina.com.cn/s/blog_6c617ee301013xt ...

  8. MySQL 5.6内存占用过高解决方案

      距离MySQL 5.6正式发布已经有比较长的时间了,目前Oracle官网上的最新GA版本MySQL server也为5.6.但reizhi在安装配置后却发现其内存占用居高不下,无论如何调整cach ...

  9. 项链(burnside)

    Description 有一个长度为 \(n\) 的项链,首尾相接形成环,现在你要给每一个位置一个颜色 \([1,m]\), 求所有不同的项链个数(可以通过旋转变成一样的称为相同) Solution ...

  10. 项目管理系列--谷歌的code review

    Google 开源项目风格指南 (中文版) 在线文档托管在 ReadTheDocs : 在线阅读最新版本 中文风格指南 GitHub 托管地址:zh-google-styleguide 声明. 本项目 ...