asp.net mvc api如何過濾xss攻擊

這裏我引用網絡上的一些代碼,然後我也進行了一些調整,以前在網絡上搜到的只支持html字符串類型的過濾,不支持json格式的過濾,代碼如下,我就不一一描述了,其實很簡單,如果有什麼不懂的,可以微信羣加入提出討論

 public class XssActionInvoker : ApiControllerActionInvoker
    {
        private static readonly ILogger _log = LoggerFactory.Logger;
        public override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> InvokeActionAsync(HttpActionContext filterContext, System.Threading.CancellationToken cancellationToken)
        {
            Dictionary<string, object> changeDictionary = new Dictionary<string, object>();
            foreach (var para in filterContext.ActionArguments)
            {
                if (para.Value?.GetType() == typeof(string))
                {
                   
                    var value = para.Value as string;
                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        value = Sanitizer.GetSafeHtmlFragment(value);
                        changeDictionary.Add(para.Key, value);
                    }
                }
                else if(para.Value!=null)
                {
                    var ty = para.Value.MToString();
                    if (ty != null && ty.Contains("{"))
                    {
                        var clss = para.Value?.GetType();
                        var obj = clss.Assembly.CreateInstance(clss.FullName);
                        try
                        {
                            //獲取接收實體類的屬性
                            var vls = clss.GetProperties();
                            //遍歷實體類的屬性
                            foreach (PropertyInfo item in vls)
                            {
                                //獲取原來的值
                                var yvue =item.GetValue(para.Value, null).ToString();
                                //檢查是否有危險字符。這裏只檢查這幾個字符
                                var isxss = !string.IsNullOrEmpty(Regex.Match(yvue, @"<|>|(|)&lt|%3c|script")?.Value);
                                if (isxss)
                                {
                                    //替換原來的內容爲安全內容
                                    var vlue = Sanitizer.GetSafeHtmlFragment(item.GetValue(para.Value, null).ToString()).Replace("script","");
                                    //給新的動態類的屬性設置值
                                    SetValue(obj, item.Name, vlue);
                                }
                                else
                                {
                                    SetValue(obj, item.Name, yvue);
                                }
                            }                           
                            changeDictionary.Add(para.Key, obj);
                         
                        }
                        catch (Exception ex)
                        {
                            if(changeDictionary?.Count>0)
                            {
                                changeDictionary.Clear();
                            }
                            _log.LogInfo("xss過濾異常:"+ex.ToString()+"|||"+ ty);
                        }
                        
                    }
                }
                

            }
            foreach (var changePara in changeDictionary)
            {
                try
                {
                    filterContext.ActionArguments[changePara.Key] = changePara.Value;
                }
                catch (Exception ex)
                {
                    _log.LogInfo("xss過濾異常:" + ex.ToString());
                    //throw;
                }
                //filterContext.ActionArguments[changePara.Key] = changePara.Value;
            }
            return base.InvokeActionAsync(filterContext, cancellationToken);
        }
        /// <summary>
        /// 設置相應屬性的值
        /// </summary>
        /// <param name="entity">實體</param>
        /// <param name="fieldName">屬性名</param>
        /// <param name="fieldValue">屬性值</param>
        public static void SetValue(object entity, string fieldName, string fieldValue)
        {
            Type entityType = entity.GetType();

            PropertyInfo propertyInfo = entityType.GetProperty(fieldName);

            if (IsType(propertyInfo.PropertyType, "System.String"))
            {
                propertyInfo.SetValue(entity, fieldValue, null);

            }

            if (IsType(propertyInfo.PropertyType, "System.Boolean"))
            {
                propertyInfo.SetValue(entity, Boolean.Parse(fieldValue), null);

            }

            if (IsType(propertyInfo.PropertyType, "System.Int32"))
            {
                if (fieldValue != "")
                    propertyInfo.SetValue(entity, int.Parse(fieldValue), null);
                else
                    propertyInfo.SetValue(entity, 0, null);

            }

            if (IsType(propertyInfo.PropertyType, "System.Decimal"))
            {
                if (fieldValue != "")
                    propertyInfo.SetValue(entity, Decimal.Parse(fieldValue), null);
                else
                    propertyInfo.SetValue(entity, new Decimal(0), null);

            }

            if (IsType(propertyInfo.PropertyType, "System.Nullable`1[System.DateTime]"))
            {
                if (fieldValue != "")
                {
                    try
                    {
                        propertyInfo.SetValue(
                            entity,
                            (DateTime?)DateTime.ParseExact(fieldValue, "yyyy-MM-dd HH:mm:ss", null), null);
                    }
                    catch
                    {
                        propertyInfo.SetValue(entity, (DateTime?)DateTime.ParseExact(fieldValue, "yyyy-MM-dd", null), null);
                    }
                }
                else
                    propertyInfo.SetValue(entity, null, null);

            }

        }
        /// <summary>
        /// 類型匹配
        /// </summary>
        /// <param name="type"></param>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public static bool IsType(Type type, string typeName)
        {
            if (type.ToString() == typeName)
                return true;
            if (type.ToString() == "System.Object")
                return false;

            return IsType(type.BaseType, typeName);
        }
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章