如何让Asp.net Web Api全局预防Xss攻击

一、概述

二、什么是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());
        }
    }

 

posted @ 2015-08-18 16:36  RyanRuan  阅读(4834)  评论(0编辑  收藏  举报
View Code