简体   繁体   中英

vNext Model Binder that filter strings

I need to filter all strings in my project to prevent XSS attacks. I decided to do it by using global model binder. Below you can see model binder registration code:

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

The requirement is to filter both simple parameter strings and strings that inside complex type (any level of nesting):

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

Example of filtering method:

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

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

No good documentation on ModelBinder topic, so any help will be appreciated.

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", "");
    }
}

Works for all levels of nesting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM