热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

再看ibatisOrderBy注入问题

接上文http:blog.itpub.net29254281viewspace-1318239领导让开发同学鼓捣一个可配置化的后台.又回到了原来的问题如果要灵活,很多参数要
接上文
http://blog.itpub.net/29254281/viewspace-1318239/

领导让开发同学鼓捣一个可配置化的后台.
又回到了原来的问题
如果要灵活,很多参数要从前端页面传过来,有SQL注入的风险.
如果参数化SQL,又很难做到灵活..

先看一个注入的例子:

  1. import java.sql.Connection;  
  2. import java.sql.DriverManager;  
  3. import java.sql.ResultSet;  
  4. import java.sql.SQLException;  
  5. import java.sql.Statement;  
  6.   
  7. public class Test {  
  8.     public static void main(String[] args) throws SQLException {  
  9.         String para="/index.html' union all select * from probe -- ";  
  10.         Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mvbox""xx""xx");  
  11.           
  12.         Statement ps=conn.createStatement();  
  13.   
  14.         ResultSet rs = ps.executeQuery("select * from probe where path='"+para+"'");  
  15.         while (rs.next()) {  
  16.             System.out.println(rs.getString("host")+":"+rs.getString("path"));  
  17.         }  
  18.         rs.close();  
  19.         ps.close();  
  20.         conn.close();  
  21.     }  

如果要避免这种风险,可以选择参数化
  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.   
  7. public class Test {  
  8.     public static void main(String[] args) throws SQLException {  
  9.         String para="/index.html' union all select * from probe -- ";  
  10.         Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mvbox""xx""xx");  
  11.         PreparedStatement ps=conn.prepareStatement("select * from probe where path=?");  
  12.         ps.setString(1, para);  
  13.         ResultSet rs=ps.executeQuery();  
  14.         while (rs.next()) {  
  15.             System.out.println(rs.getString("host")+":"+rs.getString("path"));  
  16.         }  
  17.         rs.close();  
  18.         ps.close();  
  19.         conn.close();  
  20.     }  

为何参数化可以防止注入?
作为MySQL JDBC驱动来说(5.1.31),其实就是对敏感字符做了转义.

观察 com.mysql.jdbc.PreparedStatement 的 setString方法

可以看到有如下的替换过程

  1.                String parameterAsString = x;  
  2.             boolean needsQuoted = true;  
  3.               
  4.             if (this.isLoadDataQuery || isEscapeNeededForString(x, stringLength)) {  
  5.                 needsQuoted = false// saves an allocation later  
  6.                   
  7.                 StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));  
  8.                   
  9.                 buf.append('\'');  
  10.       
  11.                 //  
  12.                 // Note: buf.append(char) is _faster_ than  
  13.                 // appending in blocks, because the block  
  14.                 // append requires a System.arraycopy()....  
  15.                 // go figure...  
  16.                 //  
  17.       
  18.                 for (int i = 0; i < stringLength; ++i) {  
  19.                     char c = x.charAt(i);  
  20.       
  21.                     switch (c) {  
  22.                     case 0/* Must be escaped for 'mysql' */  
  23.                         buf.append('\\');  
  24.                         buf.append('0');  
  25.       
  26.                         break;  
  27.       
  28.                     case '\n'/* Must be escaped for logs */  
  29.                         buf.append('\\');  
  30.                         buf.append('n');  
  31.       
  32.                         break;  
  33.       
  34.                     case '\r':  
  35.                         buf.append('\\');  
  36.                         buf.append('r');  
  37.       
  38.                         break;  
  39.       
  40.                     case '\\':  
  41.                         buf.append('\\');  
  42.                         buf.append('\\');  
  43.       
  44.                         break;  
  45.       
  46.                     case '\'':  
  47.                         buf.append('\\');  
  48.                         buf.append('\'');  
  49.       
  50.                         break;  
  51.       
  52.                     case '"'/* Better safe than sorry */  
  53.                         if (this.usingAnsiMode) {  
  54.                             buf.append('\\');  
  55.                         }  
  56.       
  57.                         buf.append('"');  
  58.       
  59.                         break;  
  60.       
  61.                     case '\032'/* This gives problems on Win32 */  
  62.                         buf.append('\\');  
  63.                         buf.append('Z');  
  64.       
  65.                         break;  
  66.   
  67.                     case '\u00a5':  
  68.                     case '\u20a9':  
  69.                         // escape characters interpreted as backslash by mysql  
  70.                         if(charsetEncoder != null) {  
  71.                             CharBuffer cbuf = CharBuffer.allocate(1);  
  72.                             ByteBuffer bbuf = ByteBuffer.allocate(1);   
  73.                             cbuf.put(c);  
  74.                             cbuf.position(0);  
  75.                             charsetEncoder.encode(cbuf, bbuf, true);  
  76.                             if(bbuf.get(0) == '\\') {  
  77.                                 buf.append('\\');  
  78.                             }  
  79.                         }  
  80.                         // fall through  
  81.   
  82.                     default:  
  83.                         buf.append(c);  
  84.                     }  
  85.                 }  
  86.       
  87.                 buf.append('\'');  
  88.       
  89.                 parameterAsString = buf.toString();  
  90.             } 


是不是可以使用 iBatis 的 $ 方式 增加灵活性,而在参数进入iBatis之前,手工进行一下敏感字符替换,而防止SQL注入攻击呢?

推荐阅读
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • 在使用 DataGridView 时,如果在当前单元格中输入内容但光标未移开,点击保存按钮后,输入的内容可能无法保存。只有当光标离开单元格后,才能成功保存数据。本文将探讨如何通过调用 DataGridView 的内置方法解决此问题。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
author-avatar
mobiledu2502931997
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有