如何防止脚本注入为中心的核心.NET MVC应用程序

问题描述 投票:1回答:1

我只是需要实现一个逻辑集中检查,如果没有加入到输入脚本的一些看法。

我打算使用antiXSS(Sanitizer.GetSafeHtmlFragment(“值”)),并检查输出是否为空,这意味着它可能包含脚本和处理错误。我可以拿出来通过模型的属性和检查值的逻辑,如果有任何可疑抛出一个错误。

我不知道是否有处理这种注射了所有输入字段一气呵成,而不是增加验证每个字段的更好的方法。

比方说,如果我有这样一个模型:

public class Login {
   public string Email {get; set;}
   public string Password {get; set;}
}

我可以再补充某种过滤检查的输入不包含任何脚本打黑行动,而不是增加一些属性模型或验证Express之前,然后为每个字段做HTML编码单独再扔一个错误。

我想在极顶的东西,所以我不通过每行动或模型,并做出一些改变。

asp.net-mvc validation asp.net-core xss
1个回答
1
投票

我使用的过滤器作用,并添加这样的代码来检查字符串类型的请求的任何模型,并且对其进行编码。它完美罚款我们。

public static class HttpEncode
{
    public static void ParseProperties(this object model)
    {
        if (model == null) return;

        if (IsPropertyArrayOrList(model.GetType()))
        {
            ParsePropertiesOfList(model);
        }
        else
        {
            GetAllProperties(model).ForEach(t => EncodeField(t, model));
        }
    }

    private static void ParsePropertiesOfList(object model)
    {
        foreach (var item in (IEnumerable) model)
        {
            ParseProperties(item);
        }
    }

    private static List<PropertyInfo> GetAllProperties(object value) => value?.GetType()?.GetProperties()?.ToList();

    private static void EncodeField(PropertyInfo p, object arg)
    {
        try
        {
            if (p.GetIndexParameters().Length != 0 || p.GetValue(arg) == null)
                return;

            if (IsUserDefinedClass(p.PropertyType) && p.CanWrite)
            {
                ParseProperties(p.GetValue(arg));
            }
            else if (IsPropertyArrayOrList(p.PropertyType) && p.CanWrite)
            {
                ParseArrayOrListProperty(p, arg);
            }
            else if (p.PropertyType == typeof(string) && p.CanWrite)
            {
                var encodedValue = HtmlEncode(p.GetValue(arg)?.ToString());
                SetPropertyValue(p, arg, encodedValue);
            }
        }
        catch (Exception ex)
        {
            // ignored
        }
    }

    private static void ParseArrayOrListProperty(PropertyInfo p, object arg)
    {
        if (p.GetValue(arg) is string[] || p.GetValue(arg) is List<string>)
        {
            SetPropertyValueOfStaringArrayType(p, arg);
        }
        else
        {
            ParsePropertiesOfList(p.GetValue(arg));
        }
    }

    private static void SetPropertyValueOfStaringArrayType(PropertyInfo propertyInfo, object arg)
    {
        if (propertyInfo.GetValue(arg) is string[] stringValue)
        {
            var result = new List<string>();
            stringValue.ToList().ForEach(l => result.Add(HtmlEncode(l)));
            SetPropertyValue(propertyInfo, arg, result.Any() ? result.ToArray() : null);
        }
        else if (propertyInfo.GetValue(arg) is List<string> listValue)
        {
            var result = new List<string>();
            listValue.ForEach(l => result.Add(HtmlEncode(l)));
            SetPropertyValue(propertyInfo, arg, result.Any() ? result : null);
        }
    }

    private static bool IsUserDefinedClass(Type type) =>
        type.IsClass &&
        !type.FullName.StartsWith("System.");

    private static bool IsPropertyArrayOrList(Type type) =>
        type.IsArray && type.GetElementType() == typeof(string) ||
        (type != typeof(string) && type.GetInterface(typeof(IEnumerable<>).FullName) != null);

    private static void SetPropertyValue(PropertyInfo propertyInfo, object allValue, object value)
    {
        propertyInfo.SetValue(allValue, value);
    }

    private static string HtmlEncode(string value) => HttpUtility.HtmlEncode(value);

}

   public class EncodeInputsActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(
        ActionExecutingContext context,
        ActionExecutionDelegate next)
    {
        ProcessHtmlEncoding(context);
        var resultContext = await next();
        // do something after the action executes; resultContext.Result will be set
    }

    private static void ProcessHtmlEncoding(ActionExecutingContext context)
    {
        context.ActionArguments.ToList().ForEach(arg => { arg.Value.ParseProperties(); });
    }
}

推荐问答