如何清理 WebAPI 模型上的输入?

Mar*_*ons 3 c# asp.net-web-api

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

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

Mar*_*ons 5

首先创建一个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));
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后只需将其注册到类或操作上,如下所示:

[HttpPost]
[SanitizeInput]
public Response Post(Object model)
{...}
Run Code Online (Sandbox Code Playgroud)