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);
        }
    }

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