欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

asp.net mvc api如何过滤xss攻击

程序员文章站 2022-06-11 23:54:04
...

这里我引用网络上的一些代码,然后我也进行了一些调整,以前在网络上搜到的只支持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);
        }
    }

asp.net mvc api如何过滤xss攻击