Something I've learned over the course of many years working in IT is that when you hit a difficult to explain problem it's very easy to say "it's the runtime's fault!" or "that's a compiler bug" to cover for the lack of explanation for your problem. The vast majority of the time, it's not true though. It's just a subtler bug in your own work that you can't see yet.
Every so often, however, it is true. And it turns out the issue I discussed the other week about Sitecore rendering a Razor error when you asked for a media item may well be an example of this.
Their explanation describes a particular set of circumstances.
Each request you make goes through
System.Web.WebPages.WebPageHttpModule
which eventually calls
System.Web.WebPages.WebPageRoute.MatchRequest()
. Part of the logic inside that method calls
WebPageRoute.FileExists()
. That in turn depends on
System.Web.Util.FileUtil.IsSuspiciousPhysicalPath()
to look for some common scenarios that might indicate a malicious request. If all that succeeds, our media requests should end up with the custom handler that Sitecore provides for these URLs. But in the scenario we discovered the custom handler wasn't called – but .Net's Razor handler was instead.
In our particular situation, if the odd file "NOT_A_VALID_FILESYSTEM_PATH" existed in the website root, and the
config setting for "relaxedUrlToFileSystemMapping"
is set to
True
, then the
IsSuspiciousPhysicalPath()
method can mess things up when the path being processed is a certain length.
Support's example was:
The next URL is requested:
http://a-test-server.local/~/media/Client-Name/print-resource-images/thumbnails/elected-representatives/Campaign-factsheet-Thumbnail-Nov-16-v3.ashx
CustomHandlers processor modifies the URL. Its current value is
http://a-test-server.local/~/media/Client-Name/print-resource-images/thumbnails/elected-representatives/sitecore_media.ashx/~/media/Client-Name/print-resource-images/thumbnails/elected-representatives/Campaign-factsheet-Thumbnail-Nov-16-v3.ashx
IsSuspiciousPhysicalPath()
method is triggered. Physical path isC:\Inetpub\wwwroot\a-test-server\Website\~\media\Client-Name\print-resource-images\thumbnails\elected-representatives\sitecore_media.ashx\~\media\Client-Name\print-resource-images\thumbnails\elected-representatives\Campaign-factsheet-Thumbnail-Nov-16-v3.ashx
Please note that/en
s are not included in physicalPath even if they are included in your request URL.physicalPath.Length is 258. The value of
FileExists
is "false".
GetRouteLevelMatch(...)
modifies the URL. Its current value ishttp://a-test-server.local/~/media/Client-Name/print-resource-images/thumbnails/elected-representatives/sitecore_media.ashx/~/media/Client-Name/print-resource-images/thumbnails/elected-representatives/Campaign-factsheet-Thumbnail-Nov-16-v3.ashx.cshtml
IsSuspiciousPhysicalPath()
method is triggered. Physical path isC:\Inetpub\wwwroot\a-test-server\Website\~\media\Client-Name\print-resource-images\thumbnails\elected-representatives\sitecore_media.ashx\~\media\Client-Name\print-resource-images\thumbnails\elected-representatives\Campaign-factsheet-Thumbnail-Nov-16-v3.ashx.cshtml
physicalPath.Length is 265. The value of
FileExists
is "true". The path has a file extension, so the media item (NOT_A_VALID_FILESYSTEM_PATH
file to be precise) is rendered as a razor view.If the initial length of "physicalPath" string was 245,
/default.cshtml
would be added.
This is a bit complicated, but working through it with the public source for the relevant bits of .Net does seem to explain the odd behaviour we saw. Including the bit where changing the length of the URL could fix the problem, but certain invalid URLs would not return the expected 404.
And in the meantime, keep an eye out for
NOT_A_VALID_FILESYSTEM_PATH
getting accidentally created if
Server.MapPath()
processes URLs with invalid characters in it...