天天看點

.NET MVC使用HtmlSanitizer過濾XSS攻擊

什麼是XSS

通過“HTML注入”篡改了網頁,插入了惡意腳本,進而在使用者在浏覽網頁時,實作控制使用者浏覽器行為的一種攻擊方式。XSS屬于用戶端代碼注入,通常注入代碼是JavaScript。差別于指令注入,SQL注入屬于服務端代碼注入。

為什麼要過濾XSS

最近接到維護性項目,客戶回報網站的富文本編輯器中圖檔無法儲存,通過排除發現是客戶的伺服器最近設定了XSS攔截,導緻帶有标簽<img src/>的标簽的富文本請求被攔截了,導緻圖檔儲存失敗。由于客戶不是太清楚伺服器XSS攔截的具體設定,給出的方案是伺服器取消XSS攔截設定,在程式中處理XSS請求。通過搜尋發現HtmlSanitizer程式集已經處理了XSS漏洞,那麼項目中我們就直接引入該程式集解決XSS漏洞問題。

安裝HtmlSanitizer

由于項目是基于.NET Framework 4.5開發的,是以通過nuget确定支援該架構的最新版本為4.0.217,通過如下指令行直接在VS中安裝:

Install-Package HtmlSanitizer -Version 4.0.217
           

官方Github位址:https://github.com/mganss/HtmlSanitizer

使用HtmlSanitizer過濾XSS

項目為MVC的項目,我們通過AOP的方式來全局過濾XSS達到代碼侵入最小,實作ActionFilterAttribute(ActionFilterAttribute的開發可以參考 MVC過濾器開發)來過濾XSS:

public class ModelFillAttribute : ActionFilterAttribute
{
    //初始化HtmlSanitizer
    private readonly HtmlSanitizer htmlSanitizer = new HtmlSanitizer();

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        var parameters = filterContext.ActionParameters;
        if (parameters == null || parameters.Count == 0)
            return;

        parameters.ForEach(parameter =>
        {
            var model = parameter.Value;
            if (model == null) return;
            var list = new ArrayList();

            if (typeof(ICollection).IsAssignableFrom(model.GetType()))
            {
                list.AddRange(model as ICollection);
            }
            else
            {
                list.Add(model);
            }

            list.ToArray().ForEach(item =>
            {
                var propertys = item.GetType().GetProperties();
                propertys.ForEach(p =>
                {
                    if (p.PropertyType.Name.ToLower().Contains("string") && p.GetValue(item) != null && p.GetSetMethod() != null)
                    {
                        //XSS過濾
                        value = HtmlXSSFilter(value);
                        p.SetValue(item, value);
                    }
                });
            });
        });

    }

    /// <summary>
    /// 過濾HTML标記,XSS過濾
    /// </summary>
    /// <param name="html">html代碼</param>
    /// <returns>過濾後的代碼</returns>
    private string HtmlXSSFilter(string html)
    {
        if(!string.IsNullOrWhiteSpace(html) && htmlSanitizer != null)
            html = htmlSanitizer.Sanitize(html);

        return html;
    }
}
           

然後直接在需要驗證的地方通過AOP調用ActionFilterAttribute過濾XSS,或者注冊為全局的ActionFilterAttribute,過濾整個項目的所有請求。

HtmlSanitizer可以配置過濾的條件,比如标簽,屬性,樣式等等,可以通過Github檢視具體是使用,本項目使用預設的配置。

項目中通過使用HtmlSanitizer程式集,快速的過濾了XSS漏洞。希望本文可以給網友一些參考和幫助,如果有描述不準确的地方歡迎回報和指正。

繼續閱讀