двойная escape-последовательность внутри url: модуль фильтрации запросов настроен на отклонение запроса, который содержит двойную escape-последовательность - PullRequest
77 голосов
/ 12 октября 2011

В моем приложении ASP.NET MVC я пытаюсь реализовать URL, как показано ниже:

/ продукта / теги / для + семей

Когда я пытаюсь запустить свое приложение с настройками по умолчанию, я получаю это сообщение с кодом ответа 404.11:

Ошибка HTTP 404.11 - Не найдено

Модуль фильтрации запросов настроен на отклонение запроса, который содержит двойную escape-последовательность.

Я могу обойти эту ошибку, внедрив код ниже в моем web.config:

  <system.webServer>
    <security>
      <requestFiltering allowDoubleEscaping="true" />
    </security>
  </system.webServer>

Итак, теперь я не получаю никаких 404.11.

Что меня интересует, так это то, какие дыры в безопасности я открываю с помощью этой реализации.

Кстати, мое приложение под .Net Framework 4.0 и работает под IIS 7.5.

Ответы [ 4 ]

51 голосов
/ 12 октября 2011

Бреши в безопасности, которые вы можете открыть, связаны с внедрением кода - HTML-внедрением, JavaScript-внедрением или SQL-внедрением.

Настройки по умолчанию защищают вас от атак неэффективно, поскольку обычные стратегии внедренияРабота.Чем больше безопасности по умолчанию вы удаляете, тем больше вам нужно думать о том, что вы делаете с вводом, предоставленным через URL-адреса, строки запроса GET, данные запроса POST, заголовки HTTP и т. Д. ...

Например, есливы создаете динамические запросы SQL на основе параметра id вашего метода действия, например:

public ActionResult Tags(string id)
{
    var sql = "SELECT * FROM Tags Where tagName = '" + id + "'";
    // DO STUFF...
}

(... что НЕ хорошая идея), по умолчаниюЗащита, установленная платформой .NET, может остановить некоторые из более опасных сценариев, например, когда пользователь запрашивает этот URL:

/product/tags/1%27;drop%20table%20Tags;%20--

Вся идея состоит в том, чтобы обрабатывать каждую часть URL-адресов и другие входные данные дляМетоды действий как возможные угрозы.Настройка безопасности по умолчанию обеспечивает некоторую защиту для вас.Каждый параметр безопасности по умолчанию, который вы изменяете, открывает немного больше потенциальных ошибок, которые вам нужно обработать вручную.

Я предполагаю, что вы не строите SQL-запросы таким образом.Но более подлый материал возникает, когда вы сохраняете пользовательский ввод в своей базе данных, а затем отображаете его.Злонамеренный пользователь может хранить в вашей базе данных JavaScript или HTML, которые не кодируются, что, в свою очередь, угрожает другим пользователям вашей системы.

2 голосов
/ 04 декабря 2018

Риск безопасности

Параметр allowDoubleEscaping применяется только к path (cs-uri-stem) и лучше всего объясняется OWASP Double Encoding .Техника используется для обхода мер безопасности с помощью URL-кодирования запроса дважды.Используя ваш URL в качестве примера:

/product/tags/for+families --> /product/tags/for%2Bfamilies --> /product/tags/for%252Bfamilies

Предположим, что существуют специальные меры безопасности для /product/tags/for+families.Прибывает запрос на /product/tags/for%252Bfamilies, который является тем же ресурсом, но не проверяется вышеупомянутыми средствами управления безопасностью.Я использовал обобщенный термин управления безопасностью, потому что это может быть что угодно, например, требующий аутентифицированного пользователя, проверка SQLi и т. Д.

Почему блокируется IIS?

Знак плюс (+) - этозарезервированный символ для RFC2396 :

Многие URI включают компоненты, состоящие из определенных специальных символов или разделенные ими.Эти символы называются «зарезервированными», поскольку их использование в компоненте URI ограничено их зарезервированным назначением.Если данные для компонента URI будут конфликтовать с зарезервированной целью, то конфликтующие данные должны быть экранированы перед формированием URI.

  reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
                "$" | ","

У Уэйда Хилмо есть отличный пост под названием Как IISблокирует символы в URL .Там много информации и справочной информации.Часть, специально предназначенная для знака плюс, выглядит следующим образом:

Так что allowDoubleEscaping / VerifyNormalization кажется довольно простым.Почему я сказал, что это вызывает путаницу?Проблема в том, что в URL появляется символ «+».Символ «+», по-видимому, не является экранированным, поскольку он не содержит «%».Кроме того, RFC 2396 отмечает его как зарезервированный символ, который может быть включен в URL, когда он находится в экранированном виде (% 2b).Но если для allowDoubleEscaping установлено значение по умолчанию false, мы заблокируем его даже в экранированном виде.Причина этого историческая: еще в первые дни HTTP, символ «+» считался сокращением для пробела.Некоторые канонизаторы, если дать URL-адрес, содержащий «+», преобразуют его в пробел.По этой причине мы считаем «+» неканоническим в URL.Мне не удалось найти какой-либо ссылки на RFC, который называет этот «+» режим, но в Интернете есть много ссылок, в которых говорится об этом как об историческом поведении.

Из моего собственного опытаЯ знаю, что когда IIS регистрирует запрос, пробелы заменяются знаком плюс.Наличие знака плюс в имени может привести к путанице при разборе журналов.

Решение

Существует три способа исправить это и два способа по-прежнему использовать знак плюс.

  1. allowDoubleEscaping=true - Это позволит двойное экранирование для всего вашего сайта / приложения.В зависимости от содержания это может быть нежелательно, если не сказать больше.Следующая команда установит allowDoubleEscaping=true.

    appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /allowDoubleEscaping:True
    
  2. alwaysAllowedUrls - Фильтрация запросов предлагает подход белого списка.При добавлении этого URL-пути к AlwaysAllowedUrls запрос не будет проверяться какими-либо другими параметрами фильтрации запросов и продолжаться в конвейере запросов IIS.Проблема заключается в том, что фильтрация запросов не будет проверять запрос на:

    • Пределы запроса: maxContentLength, maxUrl, maxQueryString
    • Глаголы
    • Запрос - параметры строки запроса будутне проверяется
    • Двойной Escape
    • Старшие битовые символы
    • Правила фильтрации запросов
    • Ограничения заголовка запроса

    Следующая командадобавит /product/tags/for+families к alwaysAllowedUrls на веб-сайте по умолчанию.

    appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"alwaysAllowedUrls.[url='/product/tags/for+families']"
    
  3. Rename - да, просто переименуйте файл / папку / controller / etc,если возможно.Это самое простое решение.

1 голос
/ 11 апреля 2019

Я сделал работу для этого. поэтому, когда вы хотите поместить зашифрованную строку в URL для (IIS) Вы должны очистить его от грязного: {";", "/", "?", ":", "@", "&", "=", "+", "$", ","}; и когда вы хотите расшифровать его и использовать снова, вы должны снова испачкать его перед расшифровкой (чтобы получить желаемый результат).

Вот мой код, надеюсь, он кому-нибудь поможет:

 public static string cleanUpEncription(string encriptedstring)
        {
            string[] dirtyCharacters = { ";", "/", "?", ":", "@", "&", "=", "+", "$", "," };
            string[] cleanCharacters = { "p2n3t4G5l6m","s1l2a3s4h","q1e2st3i4o5n" ,"T22p14nt2s", "a9t" , "a2n3nd","e1q2ua88l","p22l33u1ws","d0l1ar5","c0m8a1a"};

            foreach (string dirtyCharacter in dirtyCharacters)
            {
                encriptedstring=encriptedstring.Replace(dirtyCharacter, cleanCharacters[Array.IndexOf(dirtyCharacters, dirtyCharacter)]);
            }
            return encriptedstring;
        }

        public static string MakeItDirtyAgain(string encriptedString)
        {
            string[] dirtyCharacters = { ";", "/", "?", ":", "@", "&", "=", "+", "$", "," };
            string[] cleanCharacters = { "p2n3t4G5l6m", "s1l2a3s4h", "q1e2st3i4o5n", "T22p14nt2s", "a9t", "a2n3nd", "e1q2ua88l", "p22l33u1ws", "d0l1ar5", "c0m8a1a" };
            foreach (string symbol in cleanCharacters)
            {
                encriptedString = encriptedString.Replace(symbol, dirtyCharacters[Array.IndexOf(cleanCharacters,symbol)]);
            }
            return encriptedString;
        }
0 голосов
/ 09 августа 2018

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

Прежде всего, я НЕ рекомендую отключать этот параметр.Более уместно изменить дизайн приложения / ресурса (например, кодировать путь, передать данные в заголовок или в тело).

Хотя это более старый пост, я подумал, что поделюсь тем, какВы можете устранить эту ошибку, если вы получаете это от вызова API, используя HttpUtility.UrlPathEncode в System.Web .

Я использую RestSharp для совершения вызовов, поэтому мой пример использует RestRequest:

var tags = new[] { "for", "family" };
var apiRequest = new RestRequest($"product/tags/{HttpUtility.UrlPathEncode(string.Join("+", tags))}");

Это создает путь, равный:

/ product / tags / для% 2Bfamilies

С другой стороны, НЕ создавайте динамический запрос на основе введенных пользователем данных.Вы ДОЛЖНЫ всегда использовать SqlParameter .Кроме того, с точки зрения безопасности крайне важно возвращать значения с соответствующей кодировкой для предотвращения атак с использованием инъекций.

~ Cheers

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