热门标签 | 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注入攻击呢?

推荐阅读
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 如何将955万数据表的17秒SQL查询优化至300毫秒
    本文详细介绍了通过优化SQL查询策略,成功将一张包含955万条记录的财务流水表的查询时间从17秒缩短至300毫秒的方法。文章不仅提供了具体的SQL优化技巧,还深入探讨了背后的数据库原理。 ... [详细]
  • HTML:  将文件拖拽到此区域 ... [详细]
  • 在Java开发中,保护代码安全是一个重要的课题。由于Java字节码容易被反编译,因此使用代码混淆工具如ProGuard变得尤为重要。本文将详细介绍如何使用ProGuard进行代码混淆,以及其基本原理和常见问题。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • JUnit下的测试和suite
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文详细介绍了 Java 中 org.apache.jena.atlas.lib.ByteBufferLib 类下的 acopyArray 方法,并提供了多个实际应用中的代码示例,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文详细介绍了PostgreSQL与MySQL在SQL语法上的主要区别,包括如何使用COALESCE替代IFNULL、金额格式化的方法、别名处理以及日期处理等关键点。 ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • Bootstrap Paginator 分页插件详解与应用
    本文深入探讨了Bootstrap Paginator这款流行的JavaScript分页插件,提供了详细的使用指南和示例代码,旨在帮助开发者更好地理解和利用该工具进行高效的数据展示。 ... [详细]
  • flea,frame,db,使用,之 ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • 本文介绍了一种使用SQL Server存储过程来实现基于单一条件的高效分页查询的方法。通过示例代码,详细说明了如何构建和执行这种分页查询。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
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社区 版权所有