Подтвердить что ты не робот

Действия по проверке запроса ASP.NET: есть ли список?

Кто-нибудь знает список точно, какие триггеры ASP.NET HttpRequestValidationException? [Это за общей ошибкой: "Было обнаружено потенциально опасное значение Request.Form" и т.д.]

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

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

Спасибо.

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

EDIT 1: Привет, Oded, знаете ли вы список, который документирует условия, используемые для определения "потенциально вредоносной строки ввода"? Это то, что я ищу.

ИЗМЕНИТЬ 2: @Крис Пеббл: Да, что ты сказал.:)

4b9b3361

Ответ 1

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

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

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

  • Найдите значение < или & в значении. Если это не так, или если это последний символ в значении, то это значение ОК.
  • Если символ & находится в последовательности &# (например, &#160; для неразрывного пробела), это "опасная строка".
  • Если символ < является частью <x (где "x" - любой алфавитный символ az), <!, </ или <?, это "опасная строка".
  • В противном случае это значение ОК.

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

Ответ 2

Обновить:

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

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

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

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


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

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

HttpRequestValidationException только одним методом в System.Web имен 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] == ':'));
}

Итак, у вас это есть. Это не красиво расшифровывать, но все это есть.

Ответ 3

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

";}alert(1);function%20a(){//

Ответ 4

Попробуйте этот обычный шаблон экспрессона.

Вам может понадобиться вытеснить \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);

Ответ 5

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

  • & #
  • <От A до <Z (верхний и нижний регистр)
  • <!
  • </
  • <?

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

[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, когда они выводятся с помощью проверки на стороне сервера, но не используются при проверке на стороне клиента, поэтому этот код уже закодирован, поскольку мы только намерены увидеть его с проверкой на стороне клиента.

Ответ 6

От MSDN:

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

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