2009-02-27 2 views
3

Я написал приложение, которое обрабатывает большинство исключений изящно, с неповрежденным дизайном страницы и хорошим сообщением об ошибке. Мое приложение ловит их все в событии и добавляет исключение в HttpContext.Curent.Context.Items, а затем делает Server.Transfer на страницу Error.aspx. Я считаю, что это единственное жизнеспособное решение в ASP.NET, поскольку, похоже, нет другого способа сделать это централизованным и общим образом.Ручная обработка URI изящно в 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 и прочитайте о implementing custom HTTP Modules. Модули Http вводят этот конвейер Asp.Net и запускаются до запуска вашей страницы. Вы можете использовать его для выполнения регистрации запросов, для изменения запросов и в вашем случае для фильтрации запросов. Модуль маршрутизации Asp.Net также реализуется как настраиваемый HTTP-модуль.

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

+0

Я согласен, что это было бы лучшим решением. Если вы справитесь с проблемой до ее фактического появления, вы сохраните ресурсы сервера. Я также хочу добавить, что в вашем модуле вы, вероятно, должны присоединить функцию проверки URL-адреса к событию HttpApplication.BeginRequest. – regex

+0

Спасибо за предложение. Теперь я реализовал его несколько иначе, но, вероятно, выберет большую часть этой логики в HttpModule, когда позволит время. –

1

Я не думаю, что использование 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 

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

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

0

написание пользовательских HttpModule не работает для меня - я до сих пор получил «Запрещенные символы в пути» ошибка, но ответ на this question решить эту проблему:

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

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

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