Напишем привязчик к модели для удаления пробельных символов слева и справа и защиты от xss атак (asp.net mvc)

В asp.net mvc привязчик к модели сразу ругается и бросает исключение, если встречает html теги и html атрибуты в переданных строках. Но если указать атрибут AllowHtml, то привязчик по умолчанию, разрешает все html теги и html атрибуты. А это не безопасно, и злоумышленник может внедрить опасный код на сайт.

Так же если передать строки с пробелами слева и справа, то эти пробелы могут записаться в бд, чего не всегда хочется.

Исправим эти недочеты, используя класс, написанный в заметке Защищаемся от xss :


public class AntyXssAndRemoveSpacesModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var holderType = bindingContext.ModelMetadata.ContainerType;
        if (holderType == null)
            return base.BindModel(controllerContext, bindingContext);

        var propertyType = holderType.GetProperty(bindingContext.ModelMetadata.PropertyName);
        var attributes = propertyType.GetCustomAttributes(true);
        bool hasAttribute = attributes
            .OfType<AllowHtmlAttribute>()
            .Any();

        var provider = bindingContext.ValueProvider;
        ValueProviderResult result;

        if (!hasAttribute)
        {
            result = provider.GetValue(bindingContext.ModelName);
        }
        else
        {
            try
            {
                result = provider.GetValue(bindingContext.ModelName);
            }
            catch (HttpRequestValidationException)
            {
                result = ((IUnvalidatedValueProvider)provider).GetValue(bindingContext.ModelName, skipValidation: true);
            }
        }

        string value = result.AttemptedValue.Trim();
        if (string.IsNullOrEmpty(value))
            return null;
        value = HtmlSanitizer.RemoveInvalidHtmlTags(value).Trim();
        if (string.IsNullOrEmpty(value))
            return null;
        return value;
    }
}

Затем пропишем в Global.cs

ModelBinders.Binders.Add(typeof(string), new AntyXssAndRemoveSpacesModelBinder());

Ссылки:

  •  http://stackoverflow.com/questions/13878967/how-to-check-for-a-property-attribute-inside-a-custom-model-binder
  • http://www.bfcamara.com/post/48031562990/aspnet-mvc-default-model-binder-with-html