简体   繁体   中英

Asp.Net MVC ActionFilter to validate query params for xss

I had the situation where I wanted to do query parameter (not form parameter) xss handling* for all of my MVC flows (and hence ActionFilter was ideal); but even on Microsoft docs I couldn't find a good implementation of this (Which I thought is a very typical scenario)

So creating this wiki format of Q&A (will post my code as an answer) to publish the implementation which solved my scenario

*When I say xss handling, I wanted the code to redirect to login page (rather than let ASP.NET MVC redirect it to lets say the error page which we can control via web.config customErrors mode="On")

Here is the implementation that worked for the use-case I mention in the question

using System;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security.AntiXss;

namespace SomeAttribute
{
    public class QueryParamsXssValidate : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            try
            {
                var qs = filterContext.HttpContext.Request.QueryString;

                foreach (var keyRecvd in qs.AllKeys)
                {
                    var keyEncd = AntiXssEncoder.HtmlEncode(keyRecvd);
                    if (keyEncd != keyRecvd)
                    {
                        throw new ArgumentException($"Potentially dangerous keyRecvd: {keyRecvd}");
                    }

                    var valRecvd = qs[keyRecvd];
                    var valEncd = AntiXssEncoder.HtmlEncode(valRecvd);
                    if (valEncd != valRecvd)
                    {
                        throw new ArgumentException($"Potentially dangerous valRecvd: {valRecvd}");
                    }
                }
            }
            catch (ArgumentException e)
            {
                //logging
                loginRedirect(filterContext); //alternatively, create ExceptionHandlerAttribute and rethrow here
            }
        }

        private void loginRedirect(ActionExecutingContext filterContext)
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary
                {
                    {"controller", "main"},
                    {"action", "login"},
                    {"error", filterContext.HttpContext.Request.QueryString["error"] ?? string.Empty}
                });
        }
    }
}

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