What am I missing in this ASP.NET XSS Security Helper class?

Posted by smartcaveman on Stack Overflow See other posts from Stack Overflow or by smartcaveman
Published on 2011-11-13T01:49:09Z Indexed on 2011/11/13 1:50 UTC
Read the original article Hit count: 295

I need a generic method for preventing XSS attacks in ASP.NET. The approach I came up with is a ValidateRequest method that evaluates the HttpRequest for any potential issues, and if issues are found, redirect the user to the same page, but in a away that is not threatening to the application. (Source code below)

While I know this method will prevent most XSS attacks, I am not certain that I am adequately preventing all possible attacks while also minimizing false positives. So, what is the most effective way to adequately prevent all possible attacks, while minimizing false positives? Are there changes I should make to the helper class below, or is there an alternative approach or third party library that offers something more convincing?

public static class XssSecurity
{

public const string PotentialXssAttackExpression = "(http(s)*(%3a|:))|(ftp(s)*(%3a|:))|(javascript)|(alert)|(((\\%3C) <)[^\n]+((\\%3E) >))";

private static readonly Regex PotentialXssAttackRegex = new Regex(PotentialXssAttackExpression, RegexOptions.IgnoreCase);

public static bool IsPotentialXssAttack(this HttpRequest request)
{
    if(request != null)
    {
        string query = request.QueryString.ToString();
        if(!string.IsNullOrEmpty(query) && PotentialXssAttackRegex.IsMatch(query))
            return true;
        if(request.HttpMethod.Equals("post", StringComparison.InvariantCultureIgnoreCase))
        {
            string form = request.Form.ToString();
            if (!string.IsNullOrEmpty(form) && PotentialXssAttackRegex.IsMatch(form))
                return true;
        }
        if(request.Cookies.Count > 0)
        {
            foreach(HttpCookie cookie in request.Cookies)
            {
                if(PotentialXssAttackRegex.IsMatch(cookie.Value))
                {
                    return true;
                }
            }
        }
    }               
    return false;
}

   public static void ValidateRequest(this HttpContext context, string redirectToPath = null)
   {
       if(context == null || !context.Request.IsPotentialXssAttack()) return;

       // expire all cookies
       foreach(HttpCookie cookie in context.Request.Cookies)
       {
           cookie.Expires = DateTime.Now.Subtract(TimeSpan.FromDays(1));
           context.Response.Cookies.Set(cookie);
       }

       // redirect to safe path
       bool redirected = false;
       if(redirectToPath != null)
       {
           try
           {
               context.Response.Redirect(redirectToPath,true);
               redirected = true;
           }
           catch
           {
               redirected = false;
           }
       }
       if (redirected) 
           return;

       string safeUrl = context.Request.Url.AbsolutePath.Replace(context.Request.Url.Query, string.Empty);
       context.Response.Redirect(safeUrl,true);
   }
}

© Stack Overflow or respective owner

Related posts about ASP.NET

Related posts about security