ОК, после долгих поисков в интернете и множества экспериментов, я думаю, что наконец понял, что происходит.Моей главной проблемой был крайний уклон подтверждения.Все, что я читал, говорило о том, что я хотел услышать, а не о том, что на самом деле говорилось.Я собираюсь кратко изложить ключевые моменты, которые мне нужно было понять, чтобы ответить на мой вопрос.
Во-первых, мне нужно было понять, что IIS и ASP.Net - это два разных приложения.Вкратце, IIS делает запрос, направляет этот запрос приложению, которое его обрабатывает, получает выходные данные из приложения обработки, а затем отправляет выходные данные из приложения обратно запрашивающей стороне.ASP.Net принимает запрос от IIS, обрабатывает его, а затем передает ответ обратно в IIS.Это огромное чрезмерное обобщение всего процесса, но для моих целей здесь вполне достаточно. 1
Входящие запросы ASP.Net должны проходить через двапривратники.Модуль IIS7 RequestFiltering (настраивается в system.webserver / requestFiltering 2 ), а затем фильтры запросов ASP.Net HttpRuntime (настраиваются в system.web / httpRuntime 3 ).
Модуль IIS RequestFiltering - единственный модуль, который нормализует входящие запросы и применяет только ОДИН раз для нормализации.Еще раз повторяю, это применяется только ОДИН раз.Даже если <requestFiltering allowDoubleEscaping="true" />
, он все равно будет применять нормализацию только один раз.Таким образом, это означает, что «% 2520» будет нормализовано до «% 20».На этом этапе, если allowDoubleEscaping имеет значение false, IIS не пропустит запрос, поскольку «% 20» все еще можно нормализовать.Однако если для allowDoubleEscaping задано значение true, IIS7 передаст запрос «% 20» следующему привратнику ASP.Net.Это было причиной первой ошибки.
Фильтр Asp.net - это место, где проверяется requestPathInvalidCharacters.Так что теперь наш «% 20» недопустим, потому что по умолчанию «%» является частью requestPathInvalidCharacters.Если мы удалим «%» из этого списка, мы сделаем это через второй привратник, и ASP.Net попытается обработать наш запрос.Это стало причиной второй ошибки.
Теперь ASP.net попытается преобразовать наш виртуальный путь в физический на сервере.К сожалению, у нас все еще есть «% 20» в нашем пути вместо «», который мы хотим, поэтому ASP.Net не может найти нужный нам ресурс и выдает «ошибка не найдена».Когда я сломал свой код, путь выглядел как раз для меня, потому что я поместил часы в свойство Request.Url.Это свойство пытается быть полезным, применяя собственную нормализацию в своем методе ToString (), таким образом делая наш% 20 похожим на то, что мы хотим, даже если это не так.Это было причиной последней ошибки.
Чтобы сделать эту работу, мы могли бы написать наш собственный пользовательский модуль, который получает запрос после первых двух привратников и полностью нормализует его, прежде чем передать егоASP.Net.Однако это позволит любому символу проходить до тех пор, пока он закодирован в URL.Например, мы обычно не хотим разрешать использование «<» или «>» в наших путях, поскольку они могут использоваться для вставки тегов в наш код.Поскольку все работает прямо сейчас, <и> не пройдут фильтр ASP.Net, поскольку они являются частью requestPathInvalidCharacters.Однако они могут быть закодированы как% 253C и% 253E, если мы откроем первые два шлюза и затем нормализуем запрос в нашем собственном пользовательском модуле, прежде чем передать его ASP.Net.
В заключение, разрешив%2520, чтобы быть полностью нормализованным, не может быть сделано без создания большой дыры в безопасности.Если бы можно было сказать модулю RequestFiltering полностью нормализовать каждый полученный им запрос перед тестированием этого запроса к первым двум привратникам, то было бы намного безопаснее, но сейчас эта функциональность недоступна.
Если бы я получилчто-нибудь не так, дайте мне знать, и я надеюсь, что это кому-нибудь поможет.