asp.net - 构建输入文本区域以允许 HTML 但防止安全/脚本攻击

标签 asp.net asp.net-mvc security

平台:ASP.NET 4.0 MVC 4 C# jQuery

这就是我想做的。

我正在为我的产品构建一个简单的论坛。我想为用户提供一个文本区域来输入他们的帖子或评论。

  1. 我希望允许基本文本格式 HTML 和链接 - 例如 p、a、b、i
  2. 不需要任何其他 html 样式 - 即 div、span 等
  3. 不需要任何脚本访问权限

有什么聪明的方法可以做到这一点吗?例如,我可以允许不安全的文本并在服务器端检查它,但我怀疑我是否能够正确清理它并可能打开安全漏洞。

最好希望避免重型插件。

谢谢!

(PS - 我最糟糕的后备方案是我只允许安全文本,即保持 ASP.NET 安全性,然后对链接使用特殊标记 - 例如 [link] [b] [i])

最佳答案

更新(2020 年 2 月): Microsoft's AntiXSS library在其 Sanitizer 类上包含一个名为 GetSafeHtmlFragment 的静态方法,该方法似乎可以完成此任务。 (由 @exploring.cheerily.impresses 建议)

<小时/>

在 .NET 4.5+ 中或通过将 System.Web.Security.AntiXss 添加到旧版本的 .NET 中,有一个很好的方法可以解决此问题。我们可以将 [AllowHtml] 和自定义注释属性一起使用。该方法应将字符串内的 HTML 标记列入白名单并验证请求。

这是此作业的自定义注释属性:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
public sealed class RemoveScriptAttribute : ValidationAttribute
{
    public const string DefaultRegexPattern = @"\<((?=(?!\b(a|b|i|p)\b))(?=(?!\/\b(a|b|i|p)\b))).*?\>";

    public string RegexPattern { get; }

    public RemoveScriptAttribute(string regexPattern = null)
    {
        RegexPattern = regexPattern ?? DefaultRegexPattern;
    }

    protected override ValidationResult IsValid(object value, ValidationContext ctx)
    {
        var valueStr = value as string;
        if (valueStr != null)
        {
            var newVal = Regex.Replace(valueStr, RegexPattern, "", RegexOptions.IgnoreCase, new TimeSpan(0, 0, 0, 0, 250));

            if (newVal != valueStr)
            {
                var prop = ctx.ObjectType.GetProperty(ctx.MemberName);
                prop.SetValue(ctx.ObjectInstance, newVal);
            }
        }

        return null;
    }
}

然后你应该使用 [AllowHtml] 和 [RemoveScript] 属性来装饰你想要 HTML 的模型属性,如下所示:

public class MyModel
{
    [AllowHtml, RemoveScript]
    public string StringProperty { get; set; }
}

这将只允许

html 标签获取它。所有其他标签都将被删除,但它足够智能,可以保留标签的内部文本。例如。如果您发送:

"This is a <b>rich text<b> entered by <u>John Smith</u>."

你最终会得到这个:

"This is a <b>rich text<b> entered by John Smith."

将更多 HTML 标签列入白名单也很容易。例如。如果你想接受


,更改 DefaultRegexPattern(全局影响)或将修改后的 regexPattern 传递给 RemoveScriptAttribute 实例,如下所示:

[AllowHtml]
[RemoveScript(regexPattern: @"\<((?=(?!\b(a|b|i|p|u|br|hr)\b))(?=(?!\/\b(a|b|i|p|u)\b))).*?\>")]
public string Body { get; set; }

相关文章:

asp.net - 如何对缓存层进行单元测试

asp.net-mvc - ASP.NET MVC中的安静的bot检测和筛选

security - 创建一个经过身份验证的用户可以访问但匿名用户不能访问的安全 Orchard CMS 页面

database - 检测 SQL Server 中的故意破坏行为

c# - 是否有一个类可以在 .NET 数据和 XML 类型之间进行转换?

asp.net - asp文本框控件的CSS

c# - 使用密码 TextMode 初始化 TextBox

asp.net-mvc - ASP.NET MVC - 如何让用户确认删除

asp.net-mvc - 为 FileResult 设置 ETag - MVC 3

c# - 如何确保仅供特定用户下载的链接?