You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET requestValidationMode=4.5下如何配置HTML标签白名单?

当然可以用白名单机制!不用禁用验证也不用降级到2.0

在ASP.NET 4.5及以上版本中,完全可以通过白名单方式允许特定HTML标签通过请求验证,同时保留默认的XSS防护。我给你分享两种最实用的方案,按需选择:

方案一:针对特定字段的局部验证(适合MVC/WebForms模型场景)

如果你的WYSIWYG编辑器绑定的是某个模型字段(比如MVC里的表单模型),可以给该字段加上[AllowHtml]属性跳过默认验证,然后配合自定义验证属性实现白名单过滤。

步骤1:给模型字段添加[AllowHtml]和自定义验证属性

public class ArticleModel
{
    public int Id { get; set; }
    public string Title { get; set; }

    // 允许HTML输入,同时应用自定义白名单验证
    [AllowHtml]
    [HtmlWhitelistValidation(AllowedTags = new[] { "b", "i", "u", "p", "br", "strong", "em" })]
    public string Content { get; set; }
}

步骤2:实现自定义白名单验证属性

这里推荐用成熟的HTML清理库(比如NuGet的HtmlSanitizer)来处理,比自己写正则更安全:

using Ganss.XSS;
using System.ComponentModel.DataAnnotations;

public class HtmlWhitelistValidationAttribute : ValidationAttribute
{
    public string[] AllowedTags { get; set; } = Array.Empty<string>();

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
            return ValidationResult.Success;

        var sanitizer = new HtmlSanitizer();
        // 清空默认允许的标签,只保留我们指定的白名单
        sanitizer.AllowedTags.Clear();
        sanitizer.AllowedTags.AddRange(AllowedTags);
        // 如果需要允许特定属性(比如class),可以添加到AllowedAttributes
        // sanitizer.AllowedAttributes.Add("class");

        var sanitizedContent = sanitizer.Sanitize(value.ToString());
        // 如果清理前后内容不一致,说明存在非法标签
        if (!sanitizedContent.Equals(value.ToString(), StringComparison.Ordinal))
        {
            return new ValidationResult($"内容包含不允许的HTML标签,仅支持:{string.Join(", ", AllowedTags)}");
        }

        return ValidationResult.Success;
    }
}

这种方式的好处是精准控制,只放开需要的字段,其他字段依然受默认请求验证保护,安全性更高。

方案二:全局自定义请求验证器(适合全应用统一规则)

如果你希望整个应用对特定请求参数(比如编辑器提交的固定参数名)统一应用白名单,可以自定义RequestValidator,替换默认的验证逻辑。

步骤1:实现自定义RequestValidator

using Ganss.XSS;
using System.Web;
using System.Web.Util;

public class WhitelistRequestValidator : RequestValidator
{
    // 定义允许的标签白名单
    private readonly string[] _allowedTags = { "b", "i", "u", "p", "br", "strong", "em" };

    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
    {
        validationFailureIndex = -1;

        // 只针对编辑器的参数(比如参数名是"editorContent")应用白名单
        if (requestValidationSource == RequestValidationSource.Form 
            && collectionKey.Equals("editorContent", StringComparison.OrdinalIgnoreCase))
        {
            if (string.IsNullOrEmpty(value))
                return true;

            // 用HtmlSanitizer清理内容
            var sanitizer = new HtmlSanitizer();
            sanitizer.AllowedTags.Clear();
            sanitizer.AllowedTags.AddRange(_allowedTags);

            var sanitizedValue = sanitizer.Sanitize(value);
            // 可选:将清理后的内容替换回请求中,确保后续处理用安全内容
            context.Request.Form.Set(collectionKey, sanitizedValue);

            return true;
        }

        // 其他参数走默认的请求验证逻辑
        return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
    }
}

步骤2:在web.config中注册自定义验证器

<system.web>
    <httpRuntime requestValidationMode="4.5" />
    <pages validateRequest="true">
        <!-- 替换成你的命名空间和程序集名称 -->
        <requestValidator type="YourProjectNamespace.WhitelistRequestValidator, YourProjectAssembly" />
    </pages>
</system.web>

关键注意事项

  • 不要自己写正则过滤HTML:正则处理HTML很容易遗漏漏洞(比如嵌套标签、属性中的脚本注入),一定要用成熟的HTML清理库(比如HtmlSanitizer)。
  • 双重防护:前端编辑器也可以做一层标签过滤,比如配置编辑器只允许白名单内的标签提交,减少后端压力。
  • 存储前再清理:即使通过了请求验证,存储到数据库前最好再做一次清理,避免后续输出时出现风险。

内容的提问来源于stack exchange,提问作者meehocz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:04:55