Причины проверки запроса ASP.NET: есть ли список? - PullRequest
26 голосов
/ 04 февраля 2010

Кто-нибудь знает список точно, что вызывает исключение HttpRequestValidationException в ASP.NET? [Это скрывается за общей ошибкой: «Обнаружено потенциально опасное значение Request.Form» и т. Д.]

Я проверил здесь, в Интернете и в библиотеке MSDN, но не могу найти это документально. Я знаю о некоторых способах создания ошибки, но хотел бы иметь полный список, чтобы я мог защититься от него и выборочно обойти его (я знаю, как отключить проверку запроса для страницы, но это не вариант в этом случай).

Это случай "безопасности через мрак"?

Спасибо.

[Примечание: скрипты не будут загружаться для меня в IE8 (как часто описывается на Мета-форуме), поэтому я не смогу "Добавить комментарий".]

РЕДАКТИРОВАТЬ 1: Привет Одед, вам известен список, в котором задокументированы условия, используемые для определения «потенциально вредоносной строки ввода»? Это то, что я ищу.

РЕДАКТИРОВАТЬ 2: @ Крис Пеббл: Да, что вы сказали. :)

Ответы [ 6 ]

35 голосов
/ 10 февраля 2010

Я не смог найти документ с изложением окончательного списка, но, просматривая Reflector и выполняя некоторый анализ использования HttpRequestValidationException, похоже, что ошибки проверки в следующих случаях могут привести к сбою проверки запроса:

  • Имя файла в одном из файлов, помещенных для загрузки.
  • Необработанный URL входящего запроса.
  • Часть значения пары имя / значение из любого из входящих файлов cookie.
  • Часть значения пары имя / значение из любого поля, входящего через GET / POST.

Тогда возникает вопрос: «что квалифицирует одну из этих вещей как опасный вклад?» Похоже, что это происходит во время внутреннего метода System.Web.CrossSiteScriptingValidation.IsDangerousString (string, out int), который выглядит так, как он решает следующим образом:

  1. Найдите значение < или &. Если его там нет или если он является последним символом в значении, тогда значение ОК.
  2. Если символ & находится в последовательности &# (например, &#160; для неразрывного пробела), это «опасная строка».
  3. Если символ < является частью <x (где «x» - любой алфавитный символ a-z), <!, </ или <?, это «опасная строка».
  4. Если все это не выполнить, значение в порядке.

Кажется, что тип System.Web.CrossSiteScriptingValidation содержит другие методы для определения того, являются ли вещи опасными URL-адресами или допустимыми идентификаторами JavaScript, но они не отображаются, по крайней мере, в результате анализа Reflector, в результате чего выдается HttpRequestValidationExceptions.

16 голосов
/ 10 февраля 2010

Обновление:

Предупреждение: Некоторые части кода в исходном ответе (ниже) были удалены и помечены как OBSOLETE.

Последний исходный код на сайте Microsoft (с подсветкой синтаксиса):

http://referencesource.microsoft.com/#System.Web/CrossSiteScriptingValidation.cs

После проверки самого нового кода вы, вероятно, согласитесь с тем, что Травис Иллиг объяснил - это единственные проверки, используемые сейчас в 2018 году (и, похоже, не изменились с 2014 года, когда был выпущен источник в GitHub ). Но старый код, приведенный ниже, все еще может иметь значение, если вы используете более старую версию фреймворка.


Оригинальный ответ:

Используя Reflector, я немного просмотрел. Вот необработанный код. Когда у меня будет время, я переведу это в несколько значимых правил:

HttpRequestValidationException генерируется только одним методом в пространстве имен System.Web, поэтому он довольно изолирован. Вот метод:

private void ValidateString(string s, string valueName, string collectionName)
{
    int matchIndex = 0;
    if (CrossSiteScriptingValidation.IsDangerousString(s, out matchIndex))
    {
        string str = valueName + "=\"";
        int startIndex = matchIndex - 10;
        if (startIndex <= 0)
        {
            startIndex = 0;
        }
        else
        {
            str = str + "...";
        }
        int length = matchIndex + 20;
        if (length >= s.Length)
        {
            length = s.Length;
            str = str + s.Substring(startIndex, length - startIndex) + "\"";
        }
        else
        {
            str = str + s.Substring(startIndex, length - startIndex) + "...\"";
        }
        throw new HttpRequestValidationException(HttpRuntime.FormatResourceString("Dangerous_input_detected", collectionName, str));
    }
}

Этот метод выше вызывает метод IsDangerousString в классе CrossSiteScriptingValidation, который проверяет строку на соответствие ряду правил. Это выглядит следующим образом:

internal static bool IsDangerousString(string s, out int matchIndex)
{
    matchIndex = 0;
    int startIndex = 0;
    while (true)
    {
        int index = s.IndexOfAny(startingChars, startIndex);
        if (index < 0)
        {
            return false;
        }
        if (index == (s.Length - 1))
        {
            return false;
        }
        matchIndex = index;
        switch (s[index])
        {
            case 'E':
            case 'e':
                if (IsDangerousExpressionString(s, index))
                {
                    return true;
                }
                break;

            case 'O':
            case 'o':
                if (!IsDangerousOnString(s, index))
                {
                    break;
                }
                return true;

            case '&':
                if (s[index + 1] != '#')
                {
                    break;
                }
                return true;

            case '<':
                if (!IsAtoZ(s[index + 1]) && (s[index + 1] != '!'))
                {
                    break;
                }
                return true;

            case 'S':
            case 's':
                if (!IsDangerousScriptString(s, index))
                {
                    break;
                }
                return true;
        }
        startIndex = index + 1;
    }
}

Этот метод IsDangerousString, по-видимому, ссылается на ряд правил проверки, которые изложены ниже:

private static bool IsDangerousExpressionString(string s, int index)
{
    if ((index + 10) >= s.Length)
    {
        return false;
    }
    if ((s[index + 1] != 'x') && (s[index + 1] != 'X'))
    {
        return false;
    }
    return (string.Compare(s, index + 2, "pression(", 0, 9, true, CultureInfo.InvariantCulture) == 0);
}

-

private static bool IsDangerousOnString(string s, int index)
{
    if ((s[index + 1] != 'n') && (s[index + 1] != 'N'))
    {
        return false;
    }
    if ((index > 0) && IsAtoZ(s[index - 1]))
    {
        return false;
    }
    int length = s.Length;
    index += 2;
    while ((index < length) && IsAtoZ(s[index]))
    {
        index++;
    }
    while ((index < length) && char.IsWhiteSpace(s[index]))
    {
        index++;
    }
    return ((index < length) && (s[index] == '='));
}

-

private static bool IsAtoZ(char c)
{
    return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')));
}

-

private static bool IsDangerousScriptString(string s, int index)
{
    int length = s.Length;
    if ((index + 6) >= length)
    {
        return false;
    }
    if ((((s[index + 1] != 'c') && (s[index + 1] != 'C')) || ((s[index + 2] != 'r') && (s[index + 2] != 'R'))) || ((((s[index + 3] != 'i') && (s[index + 3] != 'I')) || ((s[index + 4] != 'p') && (s[index + 4] != 'P'))) || ((s[index + 5] != 't') && (s[index + 5] != 'T'))))
    {
        return false;
    }
    index += 6;
    while ((index < length) && char.IsWhiteSpace(s[index]))
    {
        index++;
    }
    return ((index < length) && (s[index] == ':'));
}

Так что у вас это есть. Это не красиво, чтобы расшифровать, но это все там.

2 голосов
/ 15 апреля 2011

Как насчет этого скрипта? Ваш код не может обнаружить этот скрипт, верно?

";}alert(1);function%20a(){//
0 голосов
/ 07 декабря 2018

Исходя из ответа Трэвиса, список «опасных» последовательностей символов можно упростить следующим образом:

Исходя из этого, в веб-приложении ASP.Net MVC можно использовать следующий атрибут проверки Regex в поле модели для запуска проверки на стороне клиента до того, как HttpRequestValidationException при отправке формы; 1017 *

[RegularExpression(@"^(?![\s\S]*(&#|<[a-zA-Z!\/?]))[\s\S]*$", ErrorMessage = "This field does not support HTML or allow any of the following character sequences; &quot;&amp;#&quot;, &quot;&lt;A&quot; through to &quot;&lt;Z&quot; (upper and lower case), &quot;&lt;!&quot;, &quot;&lt;/&quot; or &quot;&lt;?&quot;.")]

Обратите внимание, что сообщения об ошибках атрибута проверки кодируются в формате HTML при выводе путем проверки на стороне сервера, но не используются при проверке на стороне клиента, поэтому это сообщение уже закодировано, так как мы намерены видеть его только с проверкой на стороне клиента.

0 голосов
/ 10 мая 2013

Попробуйте этот шаблон регулярных выражений.

Вам может понадобиться закрыть \ for javascript ex \\

var regExpPattern = '[eE][xX][pP][rR][eE][sS][sS][iI][oO][nN]\\(|\\b[oO][nN][a-zA-Z]*\\b\\s*=|&#|<[!/a-zA-Z]|[sS][cC][rR][iI][pP][tT]\\s*:';
var re = new RegExp("","gi");
re.compile(regExpPattern,"gi");
var outString = null;
outString = re.exec(text);
0 голосов
/ 04 февраля 2010

С MSDN :

'Исключение, которое выдается при получении потенциально вредоносной входной строки от клиента как части данных запроса. «

Во многих случаях это происходит, когда JavaScript изменяет значения серверного элемента управления таким образом, что ViewState не соглашается с опубликованными данными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...