10

我的一些模型属性由 AllowHtml 属性标记。有没有办法自动将 AntiXss 保护(即仅过滤允许的标签)应用于这些字段?

4

4 回答 4

10

首先,afaik,没有内置任何东西。但是 MVC 允许通过自定义 ModelBinders 轻松地做这些事情,你可以定义你的

public class CustomAntiXssAttribute : Attribute { }

AllowHtmlAttribute并用它装饰你的属性(如果你愿意,甚至可以继承)。然后使用模型绑定器,您可以添加特定的反 xss 保护:

    public class CutstomModelBinder : DefaultModelBinder
    {
        protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
        {
            if (propertyDescriptor.Attributes.OfType<CustomAntiXssAttribute>().Any())
            {
                var valueResult = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name);
                var filteredValue = SOME_CUSTOM_FILTER_FUNCTION_HERE(valueResult.AttemptedValue);
                propertyDescriptor.SetValue(bindingContext.Model, filteredValue);
            }
            else // revert to the default behavior.
            {
                base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
            }
        }
    }

然后在里面SOME_CUSTOM_FILTER_FUNCTION_HERE你可以使用@Yogiraj 建议的内容,或者使用正则表达式,甚至应用基于 HtmlAgilityPack 的过滤。

PS不要忘记添加ModelBinders.Binders.DefaultBinder = new CutstomModelBinder();到Application_Start(我忘了:))

于 2012-11-24T08:59:47.583 回答
4

没有自动的方法。您可以做的最接近的是获取 AntiXss Nuget 包。然后你可以在你的控制器中使用它,如下所示:

  Microsoft.Security.Application.Sanitizer.GetSafeHtml("YourHtml");

或者

  Microsoft.Security.Application.Encoder.HtmlEncode("YourHtml");

如果你使用,你可以使用解码它

  Server.HtmlDecode("HtmlEncodedString");

希望这可以帮助。

于 2012-11-18T16:49:26.043 回答
1

我会用数据注释验证替换这些AllowHtml属性。RegularExpression通过这种方式,您可以捕获错误并向用户显示出了什么问题,而前者在全局级别触发错误。

例如。

public class MyViewModel
{
    [DataType(DataType.MultilineText)]
    [RegularExpression(@"^[^\<\>]*$", ErrorMessage = "May not contain <,>")]
    public string Text { get; set; }
}

参考:正则表达式验证器将正则表达式 < & > 符号编码为 < >,导致 jQuery 验证失败

于 2012-11-26T12:16:11.887 回答
0

未经测试的代码,

public class ADefaultModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelMetadata.RequestValidationEnabled)
        {
            var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;
            value = value.Replace("&", "");// replace existing & from the value
            var encodedValue = Microsoft.Security.Application.Encoder.HtmlEncode(value);
            bindingContext.ModelMetadata.RequestValidationEnabled = encodedValue.Contains("&"); // Whether AntiXss encoded a char to &..
        }
        return base.BindModel(controllerContext, bindingContext);
    }
}
public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ModelBinders.Binders.DefaultBinder = new ADefaultModelBinder();
于 2012-11-26T06:56:53.953 回答