如何在 Asp.net 验证属性中将 html 标记列入白名单



我正在使用 Asp.net"验证属性"来验证用户输入,目前如果用户输入任何 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>( 等,它应该像现在一样失败

我认为使用正则表达式应该比正常的字符串操作或替换所有白名单标签更快、更方便:

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] 处的组始终包含标签名称,包括所有属性,但没有开始或结束<>/。有关简短示例,请参阅此处。

只需使用 LINQ 遍历列表:

  bool contains = list.Any(x => mystring.Contains(x));
  if (contains == true)
   {
     ////codes here 
   }
   else
    {
     ////if not in list
    }

最新更新