前段时间公司又一轮安全审查,要求对各项目进行安全扫描,排查漏洞并修复,手上有几个历史项目,要求在限定的时间内全部修复并提交安全报告,也不清楚之前是如何做的漏洞修复,这次使用工具扫描出来平均每个项目都还有大概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 = ; c3 < ; 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", "");
path = path.Replace("c:" + Separator + "program files", "");
path = path.Replace("c:" + Separator + "", ""); char[] characters = path.ToCharArray();
StringBuilder resultStringBuilder = new StringBuilder();
var dictionary = CreateFortifyDictionary(); foreach (Char character in characters)
{
string value = string.Empty;
if (dictionary.TryGetValue(character.ToString(), out value))
{
resultStringBuilder.Append(value);
}
}
return resultStringBuilder.ToString();
}

3.Cross-site Scripting:Persistent 跨站脚本攻击

引用 XSS 的定义:传送到 Web 浏览器的恶意内容通常采用 JavaScript 代码片段的形式,但也可能会包含一些 HTML、Flash 或者其他任意一种可以被浏览器执行的代码。基于 XSS 的攻击手段花样百出,几乎是无穷无尽的,但通常它们都会包含传输给攻击者的私人数据(如 Cookie 或者其他会话信息)。在攻击者的控制下,指引受害者进入恶意的网络内容;或者利用易受攻击的站点,对用户的机器进行其他恶意操作。大致意思是说 由于页面在接收参数的过程中,没有进行参数的校验,可能存在 参数中存在可执行代码的漏洞。

处理办法一般是对参数进行转义加码 .NET中 引用System.Web.HttpUtility.DLL 程序集,调用下面方法:

string str= System.Web.HttpUtility.HtmlEncode(html)

用到的地方需要 反转义解码:

string html= System.Web.HttpUtility.HtmlDecode(str);

4.System Information Leak 系统信息泄露

顾名思义就是系统的内部信息在泄漏了,给系统带来安全隐患,什么意思呢?下面是摘抄的一段话:

当系统数据或调试信息通过套接字或网络连接使程序流向远程机器时,就会发生外部信息泄露。外部信息泄露会暴露有关操作系统、完整路径名、现有用户名或配置文件位置的特定数据,从而使攻击者有机可乘,它比内部信息(攻击者更难访问)泄露更严重

就是我们系统的调试信息和异常捕获信息不能暴露出来,比如这段代码Fortify 直接会检测出漏洞。

 try
{
//
}
catch(Exception ex)
{
System.Console.WriteLine(ex.Message);
}

我们或可改成这样来解决

try
{
//
}
catch(Exception ex)
{
//System.Console.WriteLine(ex.Message);
logger.Logger("系统异常:"+ex.Message,ex);
}

错误信息不应直接抛给终端,交由日志去记录。

引申一下在系统信息泄露这方面一般采用措施:

1.IIS上发布站点时关闭Debug 远程调试模式

2.定义错误页面规范错误提示信息

3.自定义客户端异常信息类,消化内部异常信息,记录日志,过滤处理后抛给客户端允许可到的异常信息

参考如下示例:

  <compilation debug="false" />
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>

其中mode 说明如下:

1. On 表示在本地和远程用户都会看到自定义错误信息。
     2. Off 禁用自定义错误信息,本地和远程用户都会看到详细的错误信息。
     3. RemoteOnly 表示本地用户将看到详细错误信息,而远程用户将会看到自定义错误信息

string message = "";
try
{
//
}
catch(WTSError ee)
{
//
message = ee.OutMessage;
logger.Logger("系统异常:" + ee.Message, ee);
}
catch(Exception ex)
{
message = "系统异常,错误类型未知";
//System.Console.WriteLine(ex.Message);
logger.Logger("系统异常:"+ex.Message,ex);
}

5. Non-Serializable Object Stored in Session 写入Session 的对象不可被序列化

这次安全描过程中也报了很多这类漏洞,不清楚写入Session 会话中的对象为什么都要可被序列化,“在session中保存的对象最好是序列化,不然很容易导致类转换的时候发生异常”这是我找到最简短的回答,根据我的理解大概是,Session对象在存储和读取的时候会自动序列化和反序列化,对于非类似于 Int,String等非一般数据类型复杂的数据结构对象存储和读取属性和状态时数据转换容易出错。

对于这类问题的处理可以参考如下:

例如下面这段会报漏洞的代码:

Session["UserToken"] = "sessionObjectValue";

可以自定义一个Session存储对象,标为可序例化,并实现ISerializable 接口

 [Serializable]
public class SessionObject : ISerializable
{
[OptionalField]
private string data; public string Data
{
get { return data; }
set { data = value; }
} public SessionObject(string data)
{
this.data = data;
} public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Data", data);
Type basetype = this.GetType().BaseType;
MemberInfo[] mi = FormatterServices.GetSerializableMembers(basetype, context);
for (int i = ; i < mi.Length; i++)
{
//由于AddValue不能添加重名值,为了避免子类变量名与基类变量名相同,将基类序列化的变量名加上基类类名
info.AddValue(basetype.FullName + "+" + mi[i].Name, ((FieldInfo)mi[i]).GetValue(this));
} } }

然后在Session写入和读取时写成这样

 //Session["UserToken"] = new SessionObject("sessionObjectValue");
Session["UserToken"] = new SessionObject("sessionObjectValue"); //string sessionObjectValue = Session["UserToken"].ToString();
string sessionObjectValue = ((SessionObject)Session["UserToken"]).Data;

6.File Separator  文件分割符

不可避免描述中也出现了这些漏洞,一般在Window环境下,不会出现这类漏洞带来的问题,如果你的系统可以要布署在Linux或Unix 环境下就有可能出现Bug了,这类问题是指在不同操作系统环境下文件路径的分割符号不一样。如果这样一个路径:“C:\tmp\test.txt” Windows 环境是:“C:\tmp\test.txt ” Linux 环境是:"/tmp/test.txt" 为了兼顾不同操作系统环境建议使用 System.IO.Path.DirectorySeparatorChar 对象对于上面的路径这样组合:

"C:" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar + "test.txt"

类似的还有换行符:windows 下是 \r\n  Linux 等其它系统下是 \n 在.NET 中使用 System.Environment.NewLine 对象。

7.Insecure Randomness 安全随机数

引用网络上的解释:

       不安全的随机数:电脑是一种具有确定性的机器,因此不可能产生真正的随机性。伪随机数生成器 (PRNG) 近似于随机算法,始于一个能计算后续数值的种子。
PRNG 包括两种类型:统计学的 PRNG 和密码学的 PRNG。统计学的 PRNG 可提供有用的统计资料,但其输出结果很容易预测,因此数据流容易复制。若安全性取决于生成数值的不可预测性,则此类型不适用。密码学的 PRNG 通过可产生较难预测的输出结果来应对这一问题。为了使加密数值更为安全,必须使攻击者根本无法、或极不可能将它与真实的随机数加以区分。通常情况下,如果并未声明 PRNG 算法带有加密保护,那么它有可能就是一个统计学的 PRNG,不应在对安全性要求较高的环境中使用,其中随着它的使用可能会导致严重的漏洞(如易于猜测的密码、可预测的加密密钥、会话劫持攻击和 DNS 欺骗)。

就是我们一般使用的随机函数并不是真正的随机产生,具有一定的可推测性,可能带来一些安全性问题,说实话此类问题不好处理涉及到密码学。如果感兴趣话可找找这方面的资料也可以先看看这篇文章 https://www.cnblogs.com/asxinyu/p/4301554.html,个人认为一般系统可以用GUID 的方案。

以上就是这次Fortify 安全扫描中遇到的几种漏洞类型,通过上述的方法基本都已解决。记得其中还遇到一个获取电脑域帐号调用C++ 类库方法非安全代码执行漏洞,还好找到另一种不用调用C++类库的方法去替换,如果避免不了要调用C++类库里的方法,如果报此类漏洞不知能有什么好的办法来处理,希望有这方面经验的园友不吝告之。

本文参考和引用的地址如下:

1. https://www.cnblogs.com/eyesmoon/p/7421477.html  Fortify扫描漏洞解决方案

2. https://blog.csdn.net/abcxy12336/article/details/52335490  针对Fortify工具扫描出几大漏洞的解决办法总结--1

3. https://www.cnblogs.com/asxinyu/p/4301554.html  开源Math.NET基础数学类库使用(14)C#生成安全的随机数

Fortify安全漏洞一般处理方法的更多相关文章

  1. ActiveX 控件漏洞挖掘之方法

    ActiveX是微软公司提出,并在1996年被正式命名的组件技术.该技术提供了一种通用的开放程序接口,使用这种技术开发的ActiveX控件可以直接集成到IE浏览器或第三方应用程序中,但由于第三方编程等 ...

  2. WP_Image_Editor_Imagick 漏洞临时解决方法

    导读 阿里云推送的一条短信通知:存放在上面的WordPress程序有WP_Image_Editor_Imagick漏洞问题,需要登入后台补丁等等的暗示.当然,如果需要在线补丁则需要升级阿里云的安骑士专 ...

  3. linux_曝出重大bash安全漏洞及修复方法

    日前Linux官方内置Bash中新发现一个非常严重安全漏洞(漏洞参考https://access.redhat.com/security/cve/CVE-2014-6271  ),黑客可以利用该Bas ...

  4. 360安全检测出的WordPress漏洞的修复方法

    1.跨站脚本攻击(XSS) 这个漏洞注意是因为用户评论可以提交代码,有安全风险.虽然你的WordPress以及是最新版,但是你的WordPress主题却不一定跟着更新!因此,需要稍微修改一下评论相关的 ...

  5. PHP程序污点型漏洞静态检测方法

    这篇文献,作者针对基于PHP语言开发的web应用程序产生的污点型漏洞,提出了一种静态代码分析检测的方法.       先解释一下什么叫污点型漏洞,由于对于用户的输入没有进行有效的过滤,使其进入敏感函数 ...

  6. web开发中常见的安全漏洞及避免方法

    1.安全攻击 1.SQL.HTML.JS.OS命令注入 2.XSS跨站脚本攻击,利用站内信任的用户,在web页面插入恶意script代码 3.CSRF跨站请求伪造,通过伪装来自信任用户的请求来利用受信 ...

  7. php反序列化漏洞绕过魔术方法 __wakeup

    0x01 前言 前天学校的ctf比赛,有一道题是关于php反序列化漏洞绕过wakeup,最后跟着大佬们学到了一波姿势.. 0x02 原理 序列化与反序列化简单介绍 序列化:把复杂的数据类型压缩到一个字 ...

  8. 那些年我们走过的坑,对Fortify的漏洞进行总结

    1.修复方案,过滤引起Log Forging漏洞的敏感字符的公共方法 /** * Log Forging漏洞校验 * @param logs * @return */ public static St ...

  9. JAVA反序列化漏洞修复解决方法

    MyObject类建立了Serializable模块,而且重新写过了readObject()变量,仅有建立了Serializable模块的类的目标才能够被实例化,沒有建立此模块的类将无法使他们的任意状 ...

随机推荐

  1. Linux--shell重定向与文件处理命令--02

    一.IO重定向 1.数据输入:键盘---标准输入,但并不是唯一输入方式 ” | passwd –stdin username #同时添加用户和密码 while line;do 循环体...$line ...

  2. maven阿里云镜像setting

    <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...

  3. 网络安全攻击与防护--HTML学习

    第一节. HTML基本语法(文末有对该文视频讲解) HTML的官方介绍什么的我就不说了,打字也挺累的,只简单介绍一下吧,其他的懂不懂都没关系. HTML全称为Hypertext Markup Lang ...

  4. 10G的变态SQL文件,如何快速打开编辑?

    工作中,偶尔需要编辑一些大文件,比如 log 文件,后者一些变态的 SQL,此时用平常的编辑器就会显得力不从心,要么直接打不开,要么打开后卡得要死. 本文就给大家推荐几款可以操作大文件的编辑器,准备好 ...

  5. Spark流式编程介绍 - 编程模型

    来源Spark官方文档 http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#programm ...

  6. css布局之居中

    CSS布局之居中 本文主要是介绍水平居中,垂直居中,还有水平垂直居中的方法 水平居中 1.行内元素水平居中 使用text-align:center;就可以实现行内元素的水平居中,但是记得要在父元素中设 ...

  7. 学习Lowdb小型本地JSON数据库

    Lowdb是轻量化的基于Node的JSON文件数据库.对于构建不依赖服务器的小型项目,使用LowDB存储和管理数据是非常不错的选择. 一:lowdb 使用及安装 在项目中的根目录安装 lowdb 命令 ...

  8. MySQL MGR集群单主模式的自动搭建和自动化故障修复

    随着MySQL MGR的版本的升级以及技术成熟,在把MHA拉下神坛之后, MGR越来越成为MySQL高可用的首选方案.MGR的搭建并不算很复杂,但是有一系列手工操作步骤,为了简便MGR的搭建和故障诊断 ...

  9. Ms Sql server 主键并发冲突解决办法

    问题原因,同事把表的自增长ID主键,改成是自定义的编号,没有严格的并发测试.在多线程同时插入数据时会引起主键冲突: 看了一些道友的文章,尝试了几个方法.经测试 使用 WITH(updlock)  可以 ...

  10. Vue函数式组件的应用

    一.函数式组件和普通组件的区别 渲染快 没有实例,意味着没有(this) 没有生命周期(没有响应式数据) 二.组件函数的使用 1. 以局部组件为例,将组件标记为 functional=ture; 因为 ...