Предотвращает ли двойное экранирование опасность?

У меня есть приложение ASP.NET MVC с маршрутом, который позволяет искать вещи через /search/ <searchterm> .

Когда я предоставляю "поиск/abc", он работает хорошо, но когда я поставлю "/search/a + b + c" (правильно закодированный url), IIS7 отклоняет запрос с помощью HTTP Error 404.11 (модуль фильтрации запросов настроен отклонить запрос, содержащий двойную escape-последовательность). Во-первых, зачем это делать? Кажется, что это ошибка, если она является частью URL-адреса, но не является частью строки запроса (/передает? Q = a + b + c работает нормально).

Теперь я могу включить двойные escape-запросы в разделе безопасности моего web.config, но я не решаюсь сделать это, так как я не понимаю последствий, и ни почему сервер не отклонил запрос "a + b + c" как часть URL-адреса, но принять как часть строки запроса.

Может кто-нибудь объяснить и дать совет, что делать?

Ответ 1

Изменить: Добавлен акцент на соответствующие разделы.

В основном: IIS является чрезмерно параноидальным. Вы можете безопасно отключить эту проверку, если вы не делаете ничего особо неразумного с декодированными данными uri (например, генерируете URI локальной файловой системы посредством конкатенации строк).

Чтобы отключить проверку, сделайте следующее (из здесь или здесь): (см. мой комментарий ниже, что влечет за собой двойное экранирование).

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

Если символ плюса является допустимым символом в входе поиска, вам нужно включить "allowDoubleEscaping", чтобы IIS мог обрабатывать такой ввод из пути URI.

Наконец, очень простое, хотя и ограниченное обходное решение - просто избегать "+" и вместо этого использовать "%20". В любом случае использование символа "+" для кодирования пробела не является допустимым кодированием url, но специфично для ограниченного набора протоколов и, вероятно, широко поддерживается для соображений обратной совместимости. Если только для целей канонизации, вы лучше избегаете кодирования пробелов как "%20"; и это прекрасно оборачивает проблему IIS7 (которая все еще может появиться для других последовательностей, таких как% 25ab.)

Ответ 2

Считаете ли вы, что поисковый URL-адрес похож на "/search/a/b/c"?

Вам нужно настроить маршрут, например

search/{*path}

И затем извлеките значения поиска из строки пути в действии.

HTHS
Чарльз

Ответ 3

Я бы просто хотел добавить некоторую информацию в ответ Eamon Nerbonne, связанный с частью вопроса "что делать" (а не объясняя, почему). Вы также можете легко изменить определенные параметры приложения с помощью

  • открытие консоли с правами администратора (Пуск - cmd - щелкните правой кнопкой мыши, запустите от имени администратора)
  • введите следующее (взято здесь: http://blogs.iis.net/thomad/archive/2007/12/17/iis7-rejecting-urls-containing.aspx):

    %windir%\system32\inetsrv\appcmd set config "YOURSITENAME" -section:system.webServer/security/requestfiltering -allowDoubleEscaping:true
    

    (вы можете, например, заменить YOURSITENAME на Default Web Site для применения этого правила к веб-сайту по умолчанию)

  • Введите, готов.

Пример:

  • Во-первых, у меня была та же проблема: Ошибка HTTP 404.11 - Модуль фильтрации запросов настроен на отказ в запросе, который содержит двойную escape-последовательность
  • Ввод текста в тексте, упомянутом выше: Drupal7-anotherSolution to HTTP Error 404.11 - The request filtering module is configured to deny a request that contains a double escape sequence.
  • Теперь он работает так, как ожидалось: Решение ошибки HTTP 404.11 - Модуль фильтрации запросов настроен на отказ от запроса, который содержит двойную escape-последовательность.

Ответ 4

Я столкнулся с этим в IIS 7.5, выполнив Server.TransferRequest() в приложении.

Кодирование имени файла вызвало проблему с двойным бегством, но если бы я не закодировал его, я бы столкнулся с "потенциально опасной ошибкой Request.Path" .

Поместите любой протокол, даже пустой, на URL-адрес, который я передаю на Server.TranferRequest(), устранил проблему.

Не работает:

context.Server.TransferRequest("/application_name/folder/bar%20bar.jpg");

Работает:

context.Server.TransferRequest("://folder/bar%20bar.jpg");