如何消除VeraCode检测中的SQL Injection Issue(CWE ID 89)

Veracode是一个检测应用程序是否存在安全漏洞的工具,更多细节请访问http://www.veracode.com

这里主要总结一下如何消除Veracode检测结果中的SQL Injection issue(CWE ID 89)

首先,先看看VeraCode对SQL Injection Issue的定义:
SQL Injection Description
SQL injection vulnerabilities occur when data enters an application from an untrusted source and is used to dynamically
construct a SQL query.  This allows an attacker to manipulate database queries in order to access, modify, or delete arbitrary data.  Depending on the platform, database type, and configuration, it may also be possible to execute administrative operations on the database, access the filesystem, or execute arbitrary system commands.  SQL injection attacks can also be used to subvert authentication and authorization schemes, which would enable an attacker to gain privileged access to restricted portions of the application.

再浏览一下VeraCode对如何解决这个问题的建议:
Recommendations
Several techniques can be used to prevent SQL injection attacks. These techniques complement each other and address
security at different points in the application. Using multiple techniques provides defense-in-depth and minimizes the likelihood
of a SQL injection vulnerability.
Use parameterized prepared statements rather than dynamically constructing SQL queries.  This will prevent the
database from interpreting the contents of bind variables as part of the query and is the most effective defense against
SQL injection.
*
Validate user-supplied input using positive filters (white lists) to ensure that it conforms to the expected format, using
centralized data validation routines when possible.
*
Normalize all user-supplied data before applying filters or regular expressions, or submitting the data to a database. This
means that all URL-encoded (%xx), HTML-encoded (&#xx;), or other encoding schemes should be reduced to the
internal character representation expected by the application. This prevents attackers from using alternate encoding
schemes to bypass filters.
*
When using database abstraction libraries such as Hibernate, do not assume that all methods exposed by the API will
automatically prevent SQL injection attacks.  Most libraries contain methods that pass arbitrary queries to the database in an unsafe manner.


通过对现有系统的实践证明,对于这类SQL Injection Issue,消除时主要遵循以下几个原则:

1)优先使用PreparedSQLStatement,使用它提供的占位符来填充SQL中的参数。

2)因为PrepareSQLStatement只支持标准的SQL,对于某些数据库厂商中中特殊的SQL语句,比如"init device xxxx"等就无能为力了。
这是我们可以使用java.text.MessageFormat.format(query, params)来填充SQL的参数。
 1      public static String parseQuery( String query, Object[] params)
 2      {
 3          try
 4          {
 5              return MessageFormat.format(query, params);
 6          }
 7          catch( Exception e)
 8          {
 9              System.out.println(e);
10              return null;
11          }
12      }


   3)Veracode会检测传入SQL的变量是否存在安全隐患(比如是否从文件中读取的,或者是否从注册表里读取的),这种情况需要重新定义1个变量,然后将其传入SQL语句中,看如下例子
      String sql = "create {0} for instance {1} on {2}  = ''{3}''";
       String executedSql 
= parseQuery(sql,
                 
new String[]{instance.getDbName(),
                              instance.getName(),
                              instance.getDeviceName(),                           
                              instance.getDeviceSize(),
});

    这里,instance是一个已经存在的对象,如果它的变量是从文件中读取的或者是依赖于程序外部的值,Veracode就认为存在安全隐患,因此我们需要做如下的调整:
 String dbName = FileUtil.removeControlCharacter(instance.getTempdbDbName());
       String instanceName 
= FileUtil.removeControlCharacter(instance.getName());
       String devName 
= FileUtil.removeControlCharacter(instance.getTempdbDeviceName());
       String executedSql 
= parseSQLQuery(IConstants.CREATE_INSTANCE_SYS_TEMP_DB,
                 
new String[]{dbName,instanceName,devName,deviceSize});
                
    其中,FileUtil.removeControlCharacter()的作用是删除String变量中的控制符,目的就是对原有的String变量进行一次过滤后,赋值给新的变量,然后再传给SQL语句。
public static final String removeControlCharacter(String input)
    {
        
if (input == null)
        {
            
return "";
        }
        StringBuilder sb 
= new StringBuilder();
        
for (int i=0; i<input.codePointCount(0, input.length()); i++)
        {
            
int codePoint = input.codePointAt(i);
            
if(!Character.isISOControl(codePoint))
            {
                sb.appendCodePoint(codePoint);
            }
        }
        
return sb.toString();
    }   

posted on 2011-09-05 14:09 想飞就飞 阅读(2353) 评论(1)  编辑  收藏 所属分类: J2EE

评论

# re: 如何消除VeraCode检测中的SQL Injection Issue(CWE ID 89) 2011-11-24 19:27 liangO

天,什么东西要求这么严格啊  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

公告


导航

<2011年11月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

统计

常用链接

留言簿(13)

我参与的团队

随笔分类(69)

随笔档案(68)

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜