网站安全通用防护代码(C#版本源码提供)

每一个开发者都会意识到,网站发布之前,需要进行安全检查。

那么如何拦截攻击者注入恶意代码?如何防御诸如跨站脚本攻击(XSS)、SQL注入攻击等恶意攻击行为?

针对目前常见的一些安全问题,结合目前一些常见的防护办法,通用权限管理系统底层增加了安全防护代码,

现将源码提供如下

namespace DotNet.Utilities

{

    /// <summary>

    /// 网站安全通用防护

    /// 

    /// 主要功能:

    ///          拦截攻击者注入恶意代码,可以防御诸如跨站脚本攻击(XSS)、SQL注入攻击等恶意攻击行为。

    /// 

    /// 修改纪录

    /// 

    /// 2013-12-27,更新正则表达式避免误报问题。

    /// 2013-01-08,更新了aspx防护脚本中referer变量冲突问题。

    /// 2013-01-09,加入了UTF7编码XSS的防护。

    /// 2013-01-28,增强了对XSS的防护。

    /// 2013-01-31,针对某些用户后台上传文件出错的问题。

    /// 2013-03-15,增强了对POST的防护。

    /// 2013-03-28,增强了对XSS的防护。

    /// 2013-04-25,对XSS防护加入了通用的防护方法。

    /// 2013-08-02,加入对XSS编码绕过的防护。

    /// 2013-08-14,增强利用样式的XSS防护。

    /// 2014-11-12,解决SQL盲注不拦截的问题。

    /// 

    /// 2014-11-12 版本:1.0 SongBiao 创建文件。   

    /// 

    /// <author>

    ///     <name>SongBiao</name>

    ///     <date>2014-11-12</date>

    /// </author>

    /// </summary>

    public partial class SecretUtil

    {

        //正则过滤字符

        private const string StrRegex = @"<[^>]+?style=[\w]+?:expression\(|\b(alert|confirm|prompt)\b|^\+/v(8|9)|<[^>]*?=[^>]*?&#[^>]*?>|\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|/\*.+?\*/|<\s*script\b|<\s*img\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";

        /// <summary>

        ///  POST请求

        /// </summary>

        /// <param name="putData">输出非法字符串</param>

        /// <returns></returns>

        public static bool PostData(out string putData)

        {

            bool result = false;

            putData = string.Empty;

            for (int i = 0; i < HttpContext.Current.Request.Form.Count; i++)

            {

                result = CheckData(HttpContext.Current.Request.Form[i].ToString(), out putData);

                if (result)

                {

                    putData = HttpContext.Current.Request.Form[i].ToString();

                    break;

                }

            }

            return result;

        }

        /// <summary>

        /// GET请求

        /// </summary>

        /// <param name="putData">输出非法字符串</param>

        /// <returns></returns>

        public static bool GetData(out string putData)

        {

            bool result = false;

            putData = string.Empty;

            for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++)

            {

                result = CheckData(HttpContext.Current.Request.QueryString[i].ToString(), out putData);

                if (result)

                {

                    putData = HttpContext.Current.Request.QueryString[i].ToString();

                    break;

                }

            }

            return result;

        }



        /// <summary>

        /// COOKIE

        /// </summary>

        /// <param name="putData">输出非法字符串</param>

        /// <returns></returns>

        public static bool CookieData(out string putData)

        {

            bool result = false;

            putData = string.Empty;

            for (int i = 0; i < HttpContext.Current.Request.Cookies.Count; i++)

            {

                result = CheckData(HttpContext.Current.Request.Cookies[i].Value.ToLower(), out putData);

                if (result)

                {

                    putData = HttpContext.Current.Request.Cookies[i].Value.ToLower();

                    break;

                }

            }

            return result;



        }

        /// <summary>

        /// UrlReferrer请求来源

        /// </summary>

        /// <param name="putData">输出非法字符串</param>

        /// <returns></returns>

        public static bool Referer(out string putData)

        {

            bool result = false;

            result = CheckData(HttpContext.Current.Request.UrlReferrer.ToString(), out putData);

            if (result)

            {

                putData = HttpContext.Current.Request.UrlReferrer.ToString();

            }

            return result;

        }

        /// <summary>

        /// 正则检查

        /// </summary>

        /// <param name="inputData">字符串</param>

        /// <param name="putData">输出非法字符串</param>

        /// <returns></returns>

        public static bool CheckData(string inputData, out string putData)

        {

            putData = string.Empty;

            //if (Regex.IsMatch(inputData.ToUpper(), StrRegex.ToUpper(),RegexOptions.IgnoreCase))

            if (Regex.IsMatch(inputData, StrRegex, RegexOptions.IgnoreCase))

            {

                putData = inputData;

                return true;

            }

            else

            {

                return false;

            }

        }

    }



}

源码在通用权限底层中的位置:

调用方法:(ASP.NET MVC参考)在Global.asax文件中增加以下方法

 

        /// <summary>

        /// 在此处进行安全检测和防范

        /// Application_BeginRequest

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        protected void Application_AcquireRequestState(object sender, EventArgs e)

        {

            HttpContext context = HttpContext.Current;

            string putData = string.Empty;

            if (Request.Cookies != null)

            {

                if (SecretUtil.CookieData(out putData))

                {

                    ResponseWarnMessage(context, "Cookie数据有恶意字符!", putData);

                }

            }

            if (Request.UrlReferrer != null)

            {

                if (SecretUtil.Referer(out putData))

                {

                    ResponseWarnMessage(context, "Referrer数据有恶意字符!", putData);

                }

            }

            if (Request.RequestType.ToUpper() == "POST")

            {

                if (SecretUtil.PostData(out putData))

                {

                    ResponseWarnMessage(context, "Post数据有恶意字符!", putData);

                }

            }

            if (Request.RequestType.ToUpper() == "GET")

            {

                if (SecretUtil.GetData(out putData))

                {

                    ResponseWarnMessage(context, "Get数据有恶意字符!", putData);

                }

            }

        }

        /// <summary>

        /// 非安全行为 输出警告信息

        /// </summary>

        /// <param name="errorMessage"></param>

        /// <param name="putData"></param>

        private void ResponseWarnMessage(HttpContext context, string errorMessage, string putData)

        {

            //记录一下恶意攻击行为

            string ipAddress = Utilities.GetIPAddress(true);

            BaseUserInfo userInfo = context.Session[DotNet.Business.Utilities.SessionName] as BaseUserInfo;

            //非安全行为同时记录到数据库和文本文件中

            LogHelper.OracleWarn(userInfo, "恶意访问行为", "来自IP:" + ipAddress + "的访问存在恶意行为:" + errorMessage + "字符内容:" + putData, " private void ResponseErrorMessage(string errorMessage, string putData)", typeof(MvcApplication), null);

            RouteData routeData = new RouteData();

            routeData.Values.Add("controller", "Error");

            routeData.Values.Add("action", "General");

            routeData.Values.Add("title", "非法访问与请求提醒");

            routeData.Values.Add("error", "你提交的" + errorMessage + "字符内容:" + putData);

            IController errorController = new ErrorController();

            errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));

            context.Response.End();

        }

 

上面的处理方法可根据需要自己调整,我是将攻击信息使用系统的日志功能记录到Oracle数据库中,并在页面显示攻击信息,

测试:在地址后加入"?action=delete from user"

 

以上安全代码也可单独放到你的程序中使用,建议尚未做安全防护的朋友尽快加上,避免受到一些常见的攻击行为骚扰。

 

你可能感兴趣的:(C#)