一、概述
二、什么是XSS
三、预防方法
四、在WebApi中如何实现
在实现之前,需要了解ASP.NET WEB API的pipeline机制。
如上,可以采用多种方式进行参数的过滤
1、重写DelegatingHandler的SendAsync方法进行过滤,结合AntiXss类库实现
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; using System.Web.Http.Controllers; using Microsoft.Security.Application; using System.Reflection; using System.ComponentModel; using System.Threading; using System.Net.Http; namespace MyNamespace { public class AntiXssHttpMessageHandler : DelegatingHandler { protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage Request, System.Threading.CancellationToken cancellationToken) { foreach (var key in Request.RequestUri.ParseQueryString().AllKeys) { var value = Sanitizer.GetSafeHtmlFragment(Request.RequestUri.ParseQueryString()[key]); if (value != Request.RequestUri.ParseQueryString()[key]) { throw new Exception(); } } return base.SendAsync(Request, cancellationToken); } } }
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.EnableSystemDiagnosticsTracing(); config.MessageHandlers.Add(new AntiXssHttpMessageHandler()); } }
2、重写ApiControllerActionInvoker的InvokeActionAsync方法
public class XssActionInvoker : ApiControllerActionInvoker { public override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> InvokeActionAsync(HttpActionContext filterContext, System.Threading.CancellationToken cancellationToken) { Dictionary<string, object> changeDictionary = new Dictionary<string, object>(); foreach (var para in filterContext.ActionArguments) { if (para.Value.GetType()==typeof(string)) { var value = para.Value as string; if (!string.IsNullOrWhiteSpace(value)) { value = Sanitizer.GetSafeHtmlFragment(value); changeDictionary.Add(para.Key, value); } } } foreach (var changePara in changeDictionary) { filterContext.ActionArguments[changePara.Key] = changePara.Value; } return base.InvokeActionAsync(filterContext, cancellationToken); } }
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionInvoker), new XssActionInvoker()); } }