如何在Asp.net ValidationAttribute中将html标签列入白名单

时间:2018-04-18 19:45:40

标签: c# asp.net-mvc validation

我正在使用Asp.net“ValidationAttribute”来验证用户输入,目前我抛出错误,如果用户输入任何html标签,如<html>,<h1>,<div>等,但我想白名单少数标签,不想抛出错误如果用户输入一些标签,如下所示不应该失败。

<strong> hello world </strong>
<p>hello </p>

但是以下内容应该失败,因为div不在

上面的白名单标记数组中
<div>hello</div> 

目前的实施:

public sealed class WhiteListAttribute : ValidationAttribute
{
    public static bool EnableWhiteListTags { get; set; }
    private static string[] whitelistTags = new[] { "strong" };

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        string str = (string)value;

        if (str != null && 
            !EnableWhiteListTags &&
            !RequestValidator.Current.InvokeIsValidRequestString(null, str, RequestValidationSource.Form, null, out int index))
        {
            return new ValidationResult($"A potentially dangerous value was detected from request {validationContext.Name}: {str}");
        }

        return ValidationResult.Success;
    }
}

如何允许用户只输入我在数组private static string[] whitelistTags = new[] { "strong" };中定义的特定html标签,所以假设用户输入任何带有html(<strong>)标签的文本,验证不应该失败但是如果用户输入任何其他带有html标签的文本,如(<div>, <p>)等,它应该会失败,因为它当前

2 个答案:

答案 0 :(得分:1)

只需使用LINQ循环浏览列表:

  bool contains = list.Any(x => mystring.Contains(x));

  if (contains == true)
   {
     ////codes here 

   }
   else
    {
     ////if not in list
    }

答案 1 :(得分:1)

我认为使用RegEx应该比普通的字符串操作更快更方便,或者替换所有列入白名单的标签:

public sealed class WhiteListAttribute : ValidationAttribute
{
    public static bool EnableWhiteListTags { get; set; }
    private static List<string> whitelistTags = new List<string>() { "strong" };
    private static Regex regex = new Regex("(</?([^>/]*)/?>)");

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        string str = (string)value;

        if (str != null && 
            ((!EnableWhiteListTags &&
            !RequestValidator.Current.InvokeIsValidRequestString(null, str, RequestValidationSource.Form, null, out int index)) ||
            (EnableWhiteListTags && !AllTagsValid(str))))
        {
            return new ValidationResult($"A potentially dangerous value was detected from request {validationContext.Name}: {str}");
        }

        return ValidationResult.Success;
    }

    private static bool AllTagsValid(string input)
    {
        var matches = regex.Matches(input);
        var tags = matches.OfType<Match>().Select(m => m.Groups[2].Value);
        return tags.All(t => whitelistTags.Contains(t.Trim()));
    }
}

在这里,我通过正则表达式获取所有标签的列表,然后检查标签是否在白名单中。 m.Groups[2]处的组始终包含标记名称incl。所有属性但没有打开或关闭<>/。有关简短示例,请参阅HERE