前段时间公司又一轮安全审查,要求对各项目进行安全扫描,排查漏洞并修复,手上有几个历史项目,要求在限定的时间内全部修复并提交安全报告,也不清楚之前是如何做的漏洞修复,这次使用工具扫描出来平均每个项目都还有大概100来个漏洞。这些漏洞包括SQL语句注入,C#后端代码,XML文件,以及前端HTML,JS代码几个方面,由于一些项目比较老旧,限定的时间又短,做大的改动如果测试不到位,很难保证不出什么问题,所以做了一些应及处理,不过这些都不失为一种手段,下面就来对这次安全漏洞的处理做个总结。

        公司的漏洞扫描分为两个阶段,第一个阶段是用Fortify这个工具来扫描,检查出漏洞,修复并出报告,第二个阶段是用APPSCAN对线上代码扫描,我们先来说说第一个阶段Fortify工具扫描出来的漏洞如何处理,至于第二阶段,后期做了再来补上。

1.SQL注入

         这一类漏洞主要是针对一些SQL语句做动态拼接时,传入一个特殊的非法字符,如 SELECT id,name FROM User WHERE deparment=1000 and  {ConditionalExpression}  其中  {ConditionalExpression} 作为参数本想在查询页面做一些动态条件的拼接,这样就会带来SQL注入的风险,如果有人通过手段将 {ConditionalExpression} 参数的值 改成这样呢 1=1  OR 2 >1  又或者 1=1  ; drop table deparment 呢这就是一个重大的安全事故了。

载SQL注入一般可以从这几方面预防:

     1.系统中连接数据库的帐号分配合适的权限,一般业务系统中数据库操作帐号,不要分配对数库结构产生改变的权限如 CREATE TABLE ,DROP XXXX 等

     2.对复杂的查询使用存储过程,预先定义好参数,在存储过程中拼接SQL语句

     3.尽量使用例如 SqlParmater 参数化传值使之成为规范

     4.对SQL语句或参数的值做特殊关键词过滤

     5.使用如MyBATIS,Hibernate ,等支持 SQL MAPPER 的 ORM框架 

     6.尽量避免SQL语句动态拼接 或用动态LINQ 替代

     公司的项目大部分都用的MyBatis ORM框架做Mapper 映射,这次漏洞扫描 SQL注入方面还好,基本没有在代码中拼接SQL的,但有一点有个别几处代码 用的是ADO.NET 读写数据库,其中在实例化Connection 对象的地方扫描出connectString 未做加密处理。后面改用项目中现有的数据库操作类库来操作就没再报漏洞了。

2.Path Manipulation 路径篡改

        这次在安全漏洞筛查和处理过程中出现最多的就是 Path Manipulation 路径篡改,手上几个项目中其中就有两个项目用到静态页面生成,涉及到大量的文件操作,如果不做处理会报很多漏洞。首先来说说我对Path Manipulation 漏洞的认识:通过代码对系统上文件的操作如果不设置白名单,黑名单的过滤检查,是一种安全隐患,比如某个公共方法中用到了,System.IO.File.Delete(path)  .NET 提供的文件删除这个方法,path是通过参数传递的,如果不做检查,在一些调用的地方,被人改成了系统某个关键文件,可能直接系统崩溃,这就是一个天大的事情了。

对此类漏洞的修复措施一般做法如下:

      1.设置白名单或黑名单

通常做法是设置白名单,危险不可枚举,我们可以认为哪些是安全的,把它们列入允许操作的清单

     2.设置文件夹安全权限

只对允许操作的文件夹设置读写权限。切不可将整个站点关件夹权限设置可写

处理Path Manipulation 路径篡改 漏洞的.Net 示例代码:

复制代码
 private static  Dictionary<string,string> CreateFortifyDictionary()         {             Dictionary<string, string> fortifyDictionary = new Dictionary<string, string>();              for(char c1 = 'a'; c1 <= 'z'; c1++)             {                 fortifyDictionary.Add(c1.ToString(), c1.ToString());             }              for (char c2 = 'A'; c2 <= 'Z'; c2++)             {                 fortifyDictionary.Add(c2.ToString(), c2.ToString());             }              for (int c3 = 0; c3 < 10; c3++)             {                 fortifyDictionary.Add(c3.ToString(), c3.ToString());             }              fortifyDictionary.Add(".", ".");             fortifyDictionary.Add(":", ":");             fortifyDictionary.Add("/", "/");                         fortifyDictionary.Add(Separator, Separator);              return fortifyDictionary;         }          public static string SecurityPathFilter(string path)         {             path = path.ToLower();             path = path.Replace("c:"+ Separator + "windows", ""