Jeremy Davis
Jeremy Davis
Sitecore, C# and web development
Article printed from: https://blog.jermdavis.dev/posts/2017/its-never-the-runtime-except-when-it-is

It's never the runtime... (Except when it is)

Published 12 June 2017
Updated 26 June 2018
.Net Bug Sitecore ~2 min. read

Bug 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.

Getting to the bottom of the issue...

When I wrote my previous post, my colleagues and I had worked out how to resolve the problem we saw, but didn't understand what the underlying issue that caused it actually was. Since then one of my colleagues has spent further time discussing our situation with the team at Sitecore Support and they've provided some really helpful feedback about what the underlying issue might be. And the surprise is that they're pinning it on a .Net Framework bug.

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 is C:\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 /ens 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 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.cshtml

  • IsSuspiciousPhysicalPath() method is triggered. Physical path is C:\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.

Getting it fixed for the future...

Support have raised an issue with Microsoft to get the underlying bug investigated and resolved – so hopefully that will get sorted in a future update to the .Net runtime. They've also marked this as an issue in Sitecore using the bug number 95341 – so if you hit a similar issue that's the number to report to Support.

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...

↑ Back to top