【问题标题】:vNext Model Binder that filter strings过滤字符串的 vNext 模型绑定器
【发布时间】:2016-06-23 13:30:59
【问题描述】:

我需要过滤项目中的所有字符串以防止 XSS 攻击。 我决定通过使用全局模型绑定器来做到这一点。 下面你可以看到模型绑定注册码:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddMvcOptions(options =>
    {
        options.ModelBinders.Add(new AntiXSSModelBinder());
    });
}

要求是过滤简单参数字符串和复杂类型内部的字符串(任何级别的嵌套):

public async Task<IActionResult> GetShippingAddress(string id)
public async Task<IActionResult> AddUpdateShippingMethod(AddUpdateShippingMethodModel model)
// AddUpdateShippingMethodModel has Text property of string type

过滤方法示例:

public class AntiXSSModelBinder : IModelBinder
{
    public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
    {
        // ...
    }

    private string FilterPotentiallyXSSEntries(string value)
    {
        return value.Replace("<", "").Replace(">", "").Replace("script", "");
    }
}

没有关于 ModelBinder 主题的好的文档,因此我们将不胜感激。

【问题讨论】:

  • 我觉得你这样做是在倒退。一般的最佳实践是在输出点进行编码,无论是视图、XML 序列化器、JSON 序列化器还是其他任何东西。相反,您将数据锁定为 HTML,您的过滤器无效,具体取决于数据的最终位置,更糟糕的是,当您使用 razor 时,如果您决定编码为实体,而不是替换为,您将面临双重编码的风险一个空格。

标签: c# asp.net-mvc asp.net-core-mvc model-binding modelbinders


【解决方案1】:
public class AntiXSSModelBinder : IModelBinder
{
    public Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelMetadata.IsComplexType)
        {
            // this type cannot be converted
            return ModelBindingResult.NoResultAsync;
        }

        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == ValueProviderResult.None)
        {
            // no entry
            return ModelBindingResult.NoResultAsync;
        }

        var model = valueProviderResult.ConvertTo(bindingContext.ModelType);

        if (bindingContext.ModelType == typeof(string))
        {
            var modelAsString = model as string;

            if (model != null)
            {
                return ModelBindingResult.SuccessAsync(bindingContext.ModelName, FilterPotentiallyXSSEntries(modelAsString));
            }
        }

        return ModelBindingResult.NoResultAsync;
    }

    private static string FilterPotentiallyXSSEntries(string value)
    {
        return value.Replace("<", "").Replace(">", "").Replace("script", "");
    }
}

适用于所有级别的嵌套。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 2018-02-16
    • 2015-04-01
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多