Изящно обрабатывайте взлом URI в ASP.NET

Я написал приложение, которое изящно обрабатывает большинство исключений, с неизменным дизайном страницы и красивым сообщением об ошибке. Мое приложение перехватывает их все в Page_Error событии, добавляет исключение, HttpContext.Curent.Context.Items а затем выполняет Server.Transfer на Error.aspx странице. Я считаю, что это единственное жизнеспособное решение в ASP.NET, поскольку, похоже, нет другого способа сделать это централизованным и универсальным способом.

Я также обрабатываю Application_Error и провожу некоторую проверку возникшего исключения, чтобы выяснить, могу ли я справиться с ним изящно или нет. Исключения, которые, как я обнаружил, я могу аккуратно обработать, возникают после того, как кто-то взломал URI, чтобы он содержал символы, которые .NET framework считает опасными или в основном просто незаконными на уровне файловой системы.

Такие URI могут выглядеть, например, так:

  • http://exmample.com/"illegal"
  • http://example.com/illegal"/
  • http://example.com/illegal /

(обратите внимание на пробел перед косой чертой в конце последнего URI).

Я бы хотел, чтобы эти URI отвечали сообщением «404 Not Found» и дружественным сообщением, а также не отправляли никаких отчетов об ошибках, чтобы избежать векторов DDOS-атак и тому подобного. Однако я не нашел элегантного способа отловить эти типы ошибок. Что я делаю сейчас осмотреть exception.TargetSite.Name имущество, и если он равен CheckInvalidPathChars, ValidatePath или CheckSuspiciousPhysicalPath, я считаю это «исключение проверки пути» и реагировать с 404.

Хотя это похоже на взлом. Во-первых, список имен методов, вероятно, неполон, а во-вторых, есть вероятность, что эти имена методов будут заменены или переименованы в строке, что приведет к поломке моего кода.

Есть ли у кого-нибудь идеи, как я могу справиться с этим менее жестко запрограммированным и гораздо более надежным в будущем способом?

PS: Я использую System.Web.Routing в своем приложении, чтобы иметь чистые и разумные URI, если это имеет какое-либо значение для любого данного решения.

Ответов (3)

Решение

Возможно, System.Web.Routing поддерживает какую-то фильтрацию URL-адресов, но довольно легко реализовать свою собственную.

Посмотрите на интерфейс System.Web.IHttpModule и прочтите о реализации пользовательских HTTP-модулей . Модули HTTP входят в этот конвейер Asp.Net и запускаются до запуска вашей страницы. Вы можете использовать его для ведения журнала запросов, для изменения запросов и, в вашем случае, для фильтрации запросов. Модуль маршрутизации Asp.Net также реализован как настраиваемый модуль HTTP.

Что вы можете сделать, так это реализовать модуль Http, который просматривает запрошенный URL-адрес и проверяет, действителен ли он. Если URL-адрес недействителен, вы можете делать все, что вам нужно, например, перенаправить его на свою 404 - не найденную страницу или просто остановить запрос.

Я не думаю, что использование System.Web.IHttpModule - правильный ответ для IIS7 +. Я пытаюсь реализовать IHttpModule для проверки пути, но исключение было создано до выполнения HttpModule.

Это мой стек исключений:

   [ArgumentException: Illegal characters in path.]
   System.IO.Path.CheckInvalidPathChars(String path) +7493413
   System.IO.Path.Combine(String path1, String path2) +40
   System.Web.Configuration.UserMapPath.GetPhysicalPathForPath(String path, VirtualDirectoryMapping mapping) +114
   System.Web.Configuration.UserMapPath.GetPathConfigFilename(String siteID, VirtualPath path, String& directory, String& baseName) +72
   System.Web.Configuration.UserMapPath.MapPath(String siteID, VirtualPath path) +30
   System.Web.Configuration.UserMapPath.MapPath(String siteID, String path) +31
   System.Web.Hosting.HostingEnvironment.MapPathActual(VirtualPath virtualPath, Boolean permitNull) +297
   System.Web.Hosting.HostingEnvironment.MapPathInternal(VirtualPath virtualPath, Boolean permitNull) +51
   System.Web.CachedPathData.GetConfigPathData(String configPath) +341
   System.Web.CachedPathData.GetVirtualPathData(VirtualPath virtualPath, Boolean permitPathsOutsideApp) +110
   System.Web.HttpContext.GetFilePathData() +36
   System.Web.HttpContext.GetConfigurationPathData() +26
   System.Web.Configuration.RuntimeConfig.GetConfig(HttpContext context) +43
   System.Web.Configuration.CustomErrorsSection.GetSettings(HttpContext context, Boolean canThrow) +41
   System.Web.HttpResponse.ReportRuntimeError(Exception e, Boolean canThrow, Boolean localExecute) +101
   System.Web.HttpRuntime.FinishRequest(HttpWorkerRequest wr, HttpContext context, Exception e) +383

и это ссылка на жизненный цикл приложения для IIS 7.0 ( http://msdn.microsoft.com/en-us/library/bb470252.aspx )

Я предполагаю, что исключение, вызванное шагом «RESOLVE CACHE»

Написание Custom HttpModule у меня не сработало - я все еще получал ошибку «Недопустимые символы в пути», но ответ на этот вопрос решил проблему:

Оказывается, этого можно избежать, установив allowDoubleEscaping = "false" для requestFiltering в web.Config. Т.е.:

<configuration>
  <system.webServer>
    <security>
      <requestFiltering allowDoubleEscaping="false" />
    </security>
  </system.webServer>
</configuration>

Возможно, это не идеальное решение (очень приветствуются любые предложения по лучшему), но оно решает проблему.