Web开发常见安全漏洞解决方法【简化版】

来源:互联网 发布:mac icon 尺寸 编辑:程序博客网 时间:2024/05/28 20:18

平时工作,多数是开发Web项目,由于一般是开发内部使用的业务系统,所以对于安全性一般不是看的很重,基本上由于是内网系统,一般也很少会受到攻击,但有时候一些系统平台,需要外网也要使用,这种情况下,各方面的安全性就要求比较高了,所以往往会交付给一些专门做安全测试的第三方机构进行测试,然后根据反馈的漏洞进行修复,如果你平常对于一些安全漏洞不够了解,那么反馈的结果往往是很残酷的,迫使你必须在很多细节上进行修复完善。本文主要根据本人项目的一些第三方安全测试结果,以及本人针对这些漏洞问题的修复方案,介绍在这方面的一些经验,希望对大家有帮助。

基本上,参加的安全测试(渗透测试)的网站,可能或多或少存在下面几个漏洞:SQL注入漏洞、跨站脚本攻击漏洞、登陆后台管理页面、IIS短文件/文件夹漏洞、系统敏感信息泄露。

1、SQL注入漏洞的出现和修复

 1)SQL注入定义:

  SQL注入攻击是黑客对数据库进行攻击的常用手段之一。随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多。但是由于程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。

  SQL注入有时候,在地址参数输入,或者控件输入都有可能进行。如在链接后加入’号,页面报错,并暴露出网站的物理路径在很多时候,很常见,当然如果关闭了Web.Config的CustomErrors的时候,可能就不会看到。

另外,Sql注入是很常见的一个攻击,因此,如果对页面参数的转换或者没有经过处理,直接把数据丢给Sql语句去执行,那么可能就会暴露敏感的信息给对方了。如下面两个页面可能就会被添加注入攻击。

①HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name from TestD ... type='U' and status>0)>0 得到第一个用户建立表的名称,并与整数进行比较,显然abc.asp工作异常,但在异常中却可以发现表的名称。假设发现的表名是xyz,则
②HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name from TestDB.dbo.sysobjects& ... tatus>0 and name not in('xyz'))>0 可以得到第二个用户建立的表的名称,同理就可得到所有用建立的表的名称。

为了屏蔽危险Sql语句的执行,可能需要对进行严格的转换,例如如果是整形的,就严格把它转换为整数,然后在操作,这样可以避免一些潜在的危险,另外对构造的sql语句必须进行Sql注入语句的过滤,如我的框架(Winform开发框架、Web开发框架等)里面就内置了对这些有害的语句和符号进行清除工作,由于是在基类进行了过滤,因此基本上子类都不用关心也可以避免了这些常规的攻击了。

复制代码
        /// <summary>        /// 验证是否存在注入代码(条件语句)        /// </summary>        /// <param name="inputData"></param>        public bool HasInjectionData(string inputData)        {            if (string.IsNullOrEmpty(inputData))                return false;            //里面定义恶意字符集合            //验证inputData是否包含恶意集合            if (Regex.IsMatch(inputData.ToLower(), GetRegexString()))            {                return true;            }            else            {                return false;            }        }        /// <summary>        /// 获取正则表达式        /// </summary>        /// <returns></returns>        private static string GetRegexString()        {            //构造SQL的注入关键字符            string[] strBadChar =            {                //"select\\s",                //"from\\s",                "insert\\s",                "delete\\s",                "update\\s",                "drop\\s",                "truncate\\s",                "exec\\s",                "count\\(",                "declare\\s",                "asc\\(",                "mid\\(",                "char\\(",                "net user",                "xp_cmdshell",                "/add\\s",                "exec master.dbo.xp_cmdshell",                "net localgroup administrators"            };            //构造正则表达式            string str_Regex = ".*(";            for (int i = 0; i < strBadChar.Length - 1; i++)            {                str_Regex += strBadChar[i] + "|";            }            str_Regex += strBadChar[strBadChar.Length - 1] + ").*";            return str_Regex;        }
复制代码

上面的语句用于判别常规的Sql攻击字符,我在数据库操作的基类里面,只需要判别即可,如下面的一个根据条件语句查找数据库记录的函数。

复制代码
        /// <summary>        /// 根据条件查询数据库,并返回对象集合        /// </summary>        /// <param name="condition">查询的条件</param>        /// <param name="orderBy">自定义排序语句,如Order By Name Desc;如不指定,则使用默认排序</param>        /// <param name="paramList">参数列表</param>        /// <returns>指定对象的集合</returns>        public virtual List<T> Find(string condition, string orderBy, IDbDataParameter[] paramList)        {            if (HasInjectionData(condition))            {                LogTextHelper.Error(string.Format("检测出SQL注入的恶意数据, {0}", condition));                throw new Exception("检测出SQL注入的恶意数据");            }            ...........................        }
复制代码

以上只是防止Sql攻击的一个方面,还有就是坚持使用参数化的方式进行赋值,这样很大程度上减少可能受到SQL注入攻击。

            Database db = CreateDatabase();            DbCommand command = db.GetSqlStringCommand(sql);            command.Parameters.AddRange(param);

 

2、跨站脚本攻击漏洞出现和修复

 跨站脚本攻击,又称XSS代码攻击,也是一种常见的脚本注入攻击。例如在下面的界面上,很多输入框是可以随意输入内容的,特别是一些文本编辑框里面,可以输入例如<script>alert('这是一个页面弹出警告');</script>这样的内容,如果在一些首页出现很多这样内容,而又不经过处理,那么页面就不断的弹框,更有甚者,在里面执行一个无限循环的脚本函数,直到页面耗尽资源为止,类似这样的攻击都是很常见的,所以我们如果是在外网或者很有危险的网络上发布程序,一般都需要对这些问题进行修复。

XSS代码攻击还可能会窃取或操纵客户会话和 Cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以及执行事务。
[建议措施]
清理用户输入,并过滤出 JavaScript 代码。我们建议您过滤下列字符: 
[1] <>(尖括号)
[2] "(引号)
[3] '(单引号)
[4] %(百分比符号)
[5] ;(分号)
[6] ()(括号)
[7] &(& 符号)
[8] +(加号)

为了避免上述的XSS代码攻击,解决办法是可以使用HttpUitility的HtmlEncode或者最好使用微软发布的AntiXSSLibrary进行处理,这个更安全。

微软反跨站脚本库(AntiXSSLibrary)是一种编码库,旨在帮助保护开发人员保护他们的基于Web的应用不被XSS攻击。 

编码方法

使用场景

示例

HtmlEncode(String)

不受信任的HTML代码。<a href=”http://www.cnblogs.com”>Click Here [不受信任的输入]</a>HtmlAttributeEncode(String)

 

不受信任的HTML属性

<hr noshade size=[不受信任的输入]>

JavaScriptEncode(String)

不受信任的输入在JavaScript中使用

<script type=”text/javascript”>

[Untrusted input]

</script>

UrlEncode(String)

 

不受信任的URL

<a href=”http://cnblogs.com/results.aspx?q=[Untrusted input]”>Cnblogs.com</a>

VisualBasicScriptEncode(String)

不受信任的输入在VBScript中使用

<script type=”text/vbscript” language=”vbscript”>

[Untrusted input]

</script>

XmlEncode(String)

不受信任的输入用于XML输出

<xml_tag>[Untrusted input]</xml_tag>

XmlAttributeEncode(String)

 

不 受信任的输入用作XML属性

<xml_tag attribute=[Untrusted input]>Some Text</xml_tag>

        protected void Page_Load(object sender, EventArgs e)        {            this.lblName.Text = Encoder.HtmlEncode("<script>alert('OK');</SCRIPT>");        }

例如上面的内容,赋值给一个Lable控件,不会出现弹框的操作。

但是,我们虽然显示的时候设置了转义,输入如果要限制它们怎么办呢,也是使用AntiXSSLibrary里面的HtmlSanitizationLibrary类库Sanitizer.GetSafeHtmlFragment即可。

        protected void btnPost_Click(object sender, EventArgs e)        {            this.lblName.Text = Sanitizer.GetSafeHtmlFragment(txtName.Text);        }

这样对于特殊脚本的内容,会自动剔除过滤,而不会记录了,从而达到我们想要的目的。

4、IIS短文件/文件夹漏洞出现和修复

 

通过猜解,可能会得出一些重要的网页文件地址,如可能在/Pages/Security/下存在UserList.aspx和MenuList.aspx文件。

[建议措施]

方案1:修改注册列表HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation的值为1 。(此修改只能禁止NTFS8.3格式文件名创建,已经存在的文件的短文件名无法移除)。该修改不能完全修复,只是禁止创建推荐使用后面的修复建议
方案2:如果你的web环境不需要asp.net的支持你可以进入Internet 信息服务(IIS)管理器 --- Web 服务扩展 - ASP.NET 选择禁止此功能。(推荐)

方案3:升级net framework 至4.0以上版本.(推荐)

4、系统敏感信息泄露出现和修复

如果页面继承一般的page,而没有进行Session判断,那么可能会被攻击者获取到页面地址,进而获取到例如用户名等重要数据的。

一般避免这种方式是对于一些需要登录才能访问到的页面,一定要进行Session判断,可能很容易给漏掉了。如我在Web框架里面,就是继承一个BasePage,BasePage 统一对页面进行一个登录判断。

    public partial class UserList : BasePage    {        protected void Page_Load(object sender, EventArgs e)        {          ...............
复制代码
    /// <summary>    /// BasePage 集成自权限基础抽象类FPage,其他页面则集成自BasePage    /// </summary>    public class BasePage : FPage    {        /// <summary>        /// 默认构造函数        /// </summary>        public BasePage()        {            this.IsFunctionControl = true;//默认页面启动权限认证        }        /// <summary>        /// 检查用户是否登录        /// </summary>        private void CheckLogin()        {            if (string.IsNullOrEmpty(Permission.Identity))            {                string url = string.Format("{0}/Pages/CommonPage/Login.aspx?userRequest={1}",                    Request.ApplicationPath.TrimEnd('/'), HttpUtility.UrlEncode(Request.Url.ToString()));                Response.Redirect(url);            }        }        /// <summary>        /// 覆盖HasFunction方法以使权限类判断是否具有某功能点的权限        /// </summary>        /// <param name="functionId"></param>        /// <returns></returns>        protected override bool HasFunction(string functionId)        {            CheckLogin();            bool breturn = false;            try            {                breturn = Permission.HasFunction(functionId);            }            catch (Exception)            {                Helper.Alerts(this, "BasePage调用权限系统的HasFunction函数出错");            }            return breturn;        }        protected override void OnInit(EventArgs e)        {            Response.Cache.SetNoStore(); //清除缓存            base.OnInit(e);            CheckLogin();        }
复制代码

否则可能会受到攻击,并通过抓包软件发现页面数据,获得一些重要的用户名或者相关信息。

还有一个值得注意的地方,就是一般这种不是很安全的网络,最好要求输入比较复杂一点的密码(强制要求),例如不能全部是数字密码或者不能是纯字符,对位数也要求多一点,因为很多人输入12345678,123456,123这样的密码,很容易被猜出来并登录系统,造成不必要的损失。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 走路脚打起泡了怎么办 剪完脚趾甲肿了怎么办 大脚趾关节处疼怎么办 战士10穿不进去怎么办 脚上皮肤干燥起皮怎么办 脚趾头冻了很痒怎么办 大脚趾里面有脓怎么办 大脚趾肉肿了怎么办 大脚趾边上肿了怎么办 大母脚趾关节疼怎么办 大脚趾有点歪了怎么办 大脚趾扭伤肿了怎么办 大脚趾外翻怎么办 知乎 颈椎带着胳膊疼怎么办 胳膊酸困无力是怎么办 腰疼引起的腿麻怎么办 手臂到手指麻痛怎么办 拔完智齿特别疼怎么办 躺着胃烧的难受怎么办 喝酒胃烧的难受怎么办 舌头破了特别疼怎么办 舌头又厚又大怎么办 牙齿咬到舌头了怎么办 舌头起了好多泡怎么办 舌头尖起泡很痛怎么办 舌头上起泡怎么办很疼 月经来了二十多天还不干净怎么办 三岁宝宝缺锌怎么办 无舌苔,舌头很红怎么办 嘴唇上肿了一块怎么办 下嘴唇突然肿了怎么办 上嘴唇突然肿厚怎么办 舌尖上火了好疼怎么办 舌头针扎似的疼怎么办 手麻了怎么办小妙招 月子生气奶少了怎么办 颈椎会引起脸麻怎么办 脑梗引起的手麻怎么办 着凉引起的腰疼怎么办 受凉引起的腰疼怎么办 着凉了腰疼厉害怎么办