Оценить/рефакторинг мой ASP.NET межсайтовый скриптинг вспомогательный класс безопасности


Я поддерживаю сайт с серьезными проблемами в области безопасности и я написал вспомогательный класс для проверки потенциальных XSS-атак. То со значением validaterequest метод предназначен для оценки класса HttpRequest для любых потенциальных проблем, а если проблемы будут найдены, перенаправить пользователя на ту же страницу, но в гостях, что не является опасным для применения.

Приложение оценивается компания HP webinspect, решение. Их первоначальный обзор включены два регулярных выражения:

  1. В "regex для простой XSS-атаки"

    /((\%3C) с <)((\%2F) В \/)*[а-З0-9\%]+((\%3Е) >)/іх

  2. "Параноидальный regex для XSS-атак"

    /((\%3C) с <)[^\Н]+((\%3Е) >)/я

Регулярное выражение я использую более строгая по c# адаптация параноик регулярных выражений. Я предпочитаю ошибаться в сторону осторожности, поэтому я бы предпочел риск отказа действительным запросов, чем позволяя недопустимый запрос должен быть обработан.

Спасибо заранее за помощь.

using System;
using System.Text.RegularExpressions;
using System.Web;

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);
   }
}


1550
2
задан 12 ноября 2011 в 06:11 Источник Поделиться
Комментарии
1 ответ

Некоторые общие идеи:


  1. Используйте предохранитель отчетности вместо большой , если блоки.

  2. Извлекать !строку.IsNullOrEmpty(запросов) && PotentialXssAttackRegex.Выполняется(запрос) состояние на метод.

  3. Извлечение отдельных проверок для различных методов. В IsPotentialXssAttack будет довольно легко читается и код различных проверок не будут смешиваться в один большой метод.

  4. Я хотел создать expireAllCookies вспомогательный метод тоже.

Окончательный код первого метода будет выглядеть так (я не проверял и не компилируется):

public static bool IsPotentialXssAttack(this HttpRequest request) {
if (request == null) {
return false;
}
if (isPotentialXssAttackQuery(request)) {
return true;
}
if (isPotentialXssAttackFormOrAnything(request)) {
return true;
}
if (isPotentialXssAttackCookie(request)) {
return true;
}

return false;
}

public static bool isPotentialXssAttackQuery(this HttpRequest request) {
string query = request.QueryString.ToString();
if (isMatch(query)) {
return true;
}
return false;
}

public static bool isMatch(string input) {
if (string.IsNullOrEmpty(query)) {
return false;
}
return PotentialXssAttackRegex.IsMatch(query);
}

// TODO: rename it
public static bool isPotentialXssAttackFormOrAnything(this HttpRequest request) {
if (!request.HttpMethod.Equals("post",
StringComparison.InvariantCultureIgnoreCase)) {
return false;
}

string form = request.Form.ToString();
if (isMatch(form)) {
return true;
}
return false;
}

public static bool isPotentialXssAttackCookie(this HttpRequest request) {
if (request.Cookies.Count <= 0) {
return false;
}

foreach (HttpCookie cookie in request.Cookies){
if (isMatch(cookie.Value)) {
return true;
}
}
return false;
}

5
ответ дан 12 ноября 2011 в 08:11 Источник Поделиться