Чи ввімкнення подвійного втечі небезпечне?


136

У мене є програма ASP.NET MVC з маршрутом, який дозволяє шукати речі через / search / <searchterm>.

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

Тепер я можу ввімкнути подвійні запити на скасування в розділі безпеки мого web.config, але я не вагаюсь робити це, оскільки я не розумію наслідків, а також чому сервер не відхиляє запит "a + b + c" як частина URL-адреси, але прийняти її як частину рядка запиту.

Може хтось пояснить і дасть поради, що робити?


7
Я також спробував, можливо, більш правильний варіант виклику Server.Url Path Encode і виявився /search/a%2520b%2520cв надбавці, що призвело до чудової помилки "Потенційно небезпечне значення Request.Path виявлено з боку клієнта (%)". Ви не можете перемогти, здається.
Джаф - Бен Дюгід

Відповіді:


158

Редагувати: додано акцент до відповідних розділів.

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

Щоб вимкнути перевірку, виконайте наступне ( звідси ): (див. Мій коментар нижче про те, що спричиняє подвійне проскакування).

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

Якщо символ плюс є дійсним символом у пошуковому введенні, вам потрібно буде включити "enableDoubleEscaping", щоб дозволити IIS обробляти такий вхід з шляху URI.

Нарешті, дуже простий, якщо обмежений спосіб вирішення - просто уникати "+" та використовувати "% 20". У будь-якому випадку, використання символу "+" для кодування простору не є дійсним кодуванням URL-адреси , а є специфічним для обмеженого набору протоколів і, ймовірно, широко підтримується з міркувань зворотної сумісності. Якщо тільки для цілей канонізації, то вам краще все-таки кодувати пробіли як "% 20"; і це чудово уникає проблеми IIS7 (яка все ще може з'явитися для інших послідовностей, таких як% 25ab.)


3
Я б відключив чек. Це клопот і не забезпечує додаткову безпеку для більшості програм.
Еймон Нербонна

3
Чи є у вас посилання / посилання на те, що досить безпечно відключити подвійне втечу? Крім того, що саме цей запобіжний захід запобігає цьому?
Олексій

15
Якщо урі з подвійним уникненням, то нерозглянуті компоненти урі можуть самі містити зарезервовані символи, і, таким чином, (частини) безкарбований урі може сам по собі бути дійсним урі. Якщо коротко, якщо ви використовуєте необмежену рядок uri для побудови нових урі - зокрема шляхів файлової системи - і ви не зможете правильно вийти з нового шляху, ви можете дозволити введення контуру. Ін'єкція шляху може дозволити зловмиснику обдурити вашу програму в обробці даних, яких вона не повинна, або заплутати їх у думці двох урі різні, коли вони насправді однакові, але просто закодовані по-різному.
Еймон Нербонна


4
@Stijn: Так: це безпечно . Все це перевіряє - це відфільтрувати запити, які, можливо, неправильно трактуються кодом помилок (esp, якщо ви подвійно декодуєте або створюєте Uri за допомогою рядка-конкату та без належного кодування). Ви не займаєтесь будь-якою обробкою, так що це значно безпечно з вашого боку. Будь-яка помилка повинна міститись у базовому коді, що обслуговує файл IIS, і я думаю, що ми можемо з упевненістю припустити, що це вже дуже і дуже ретельно перевірено бій. Знову ж таки, ця перевірка не є нічого фантазійного, вона просто закладає речі, які можуть бути розшифровані, а потім виглядають як закодований урі.
Еймон Нербонна

2

Я просто хотів би додати деяку інформацію до відповіді Еймона Нербонна, що стосується частини " що робити " у вашому запитанні (не пояснюючи, чому це стосується).
Ви також можете легко змінити налаштування певної програми

  1. відкриття консолі з правами адміністратора (Пуск - cmd - клацнути правою кнопкою миші; Запустити як адміністратор)
  2. введіть наступне (взято звідси: http://blogs.iis.net/thomad/archive/2007/12/17/iis7-rejecting-urls-contain.aspx ):

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

    (Наприклад , ви можете замінити YOURSITENAMEз Default Web Siteдля застосування цього правила сайту за замовчуванням)

  3. Вхід, готовий.

Приклад:

  1. по-перше, у мене була та сама проблема: Помилка HTTP 404.11 - Модуль фільтрації запитів налаштований для відмови у запиті, що містить подвійну послідовність виходу.
  2. Введення тексту, згаданого вище: Drupal7-інший Рішення помилки HTTP 404.11 - Модуль фільтрації запитів налаштований для відмови у запиті, що містить подвійну послідовність відходу.
  3. Зараз він працює як очікувалося: Рішення помилки HTTP 404.11 - Модуль фільтрації запитів налаштований для відмови у запиті, що містить подвійну послідовність відходу.

1

Чи думали ви про те, щоб мати пошукову URL-адресу типу "/ search / a / b / c"?

Вам потрібно встановити такий маршрут

search/{*path}

А потім дістаньте значення пошуку зі свого рядка шляху в дії.

HTH
Чарльз


Проблема полягає в тому, що інші символи, кодовані URL-адресами (включаючи сам / /), можуть бути частиною пошуку.
Олексій

Не могли б ви кодувати всі "/", які є фактично частиною пошуку, до "% 2F"?
Чарліно

0

Я зіткнувся з цим під 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");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.