如何对WebAPI模型上的输入进行消毒?

本文关键字:输入 WebAPI 模型 | 更新日期: 2023-09-27 18:10:49

我在很多地方读到,防止XSS的正确方法不是对输入进行消毒,而是在显示输出之前对输出进行html编码。

然而,我想我遇到了这个规则的例外。我有一些数据将存储在数据库中,这些数据由我无法控制的其他遗留应用程序使用,这些应用程序可能对输出进行编码,也可能不编码。

如何对WebAPI模型上的输入进行消毒?

首先创建一个ActionFilterAttribute:

using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Microsoft.Security.Application;
/// <summary>
/// Sanitizes (HTML encodes) all strings on the model.
/// </summary>
/// <remarks>Use sparingly. Ideally don't use this and instead encode when outputting the values.
/// This is used because we don't have control of other applications that may consume the data.</remarks>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class SanitizeInputAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ActionArguments != null && actionContext.ActionArguments.Count == 1)
        {
            var requestParam = actionContext.ActionArguments.First();
            var properties = requestParam.Value.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
                .Where(x => x.CanRead && x.CanWrite && x.PropertyType == typeof(string) && x.GetGetMethod(true).IsPublic && x.GetSetMethod(true).IsPublic);
            foreach (var propertyInfo in properties)
            {
                propertyInfo.SetValue(requestParam.Value, Encoder.HtmlEncode(propertyInfo.GetValue(requestParam.Value) as string));
            }
        }
    }
}

然后简单地将它注册到类或操作上,像这样:

[HttpPost]
[SanitizeInput]
public Response Post(Object model)
{...}