Use any characters you want in your URLs with ASP.NET 4 and IIS 7!

After spending entirely too much time researching this issue today here is how you can use any characters you want for URLs in ASP.NET 4 and IIS 7. A bit of background: I am writing a web application that has a custom HttpModule and HttpHandler that should handle all requests and not limit the syntax of those requests at all. I could not find the information on how to do this in one place anywhere, and there are a reasonable amount of misleading, unanswered and naive responses on various forums that will likely lead you astray if you have an advanced configuration like mine. There are also a lot of completely out of date posts centered on .NET 1.1 and .NET 2.0.

The first thing I was trying to do was make a POST-ed form value containing a forward slash into something that could be used as a component in a RESTful URL. I tried to accomplish that by implementing a handler for AuthenticateRequest in my HttpModule (you can’t do it in BeginRequest unless you want to read the form data manually because Request.Form is not intialized yet) that would encode the value and call TransferRequest. First that made this happen:

A potentially dangerous Request.Path value was detected from the client (%).

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: A potentially dangerous Request.Path value was detected from the client (%).

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below

Stack Trace:

[HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (%).]
   System.Web.HttpRequest.ValidateInputIfRequiredByConfig() +8815985
   System.Web.PipelineStepManager.ValidateHelper(HttpContext context) +59

Okay. ASP.NET, for security reasons, normally protects your web applications from potentially harmful content being sent to them, which is probably a good thing. But what if we want or need potentially harmful content? Should we be limited? I hoped the answer was “no”, but the almost complete lack of information on the subject sure wasn’t making it seem that way. After some not too helpful reading and some digging with Reflector, I came up with this:

<httpRuntime requestPathInvalidCharacters="" />
<pages validateRequest="false" />

Now no characters are invalid and requests shouldn’t even BE validated right? WRONG. While this did clear up the first exception, I faced a new one. And, while I was not sure if the validateRequest setting would even apply to my case since it is on the pages element, I assure you that for some reason that setting is an integral part of the above and following changes to work properly together. Here was my second roadblock:

Error Summary

HTTP Error 404.11 – Not Found

The request filtering module is configured to deny a request that contains a double escape sequence.

Detailed Error Information
Module RequestFilteringModule
Notification BeginRequest
Handler Clear
Error Code 0x00000000
Requested URL http://localhost:80/Clear/search/x%2Fy
Physical Path D:\Development\Clear\Clear\search\x%2Fy
Logon Method Not yet determined
Logon User Not yet determined
Most likely causes:
  • The request contained a double escape sequence and request filtering is configured on the Web server to deny double escape sequences.
Things you can try:
  • Verify the configuration/system.webServer/security/requestFiltering@allowDoubleEscaping setting in the applicationhost.config or web.confg file.
Links and More Information

This is a security feature. Do not change this feature unless the scope of the change is fully understood. You should take a network trace before changing this value to confirm that the request is not malicious. If double escape sequences are allowed by the server, modify the configuration/system.webServer/security/requestFiltering@allowDoubleEscaping setting. This could be caused by a malformed URL sent to the server by a malicious user.View more information »

Great, now it didn’t even look like it was getting from IIS to ASP.NET! However, deciding I “fully understood” the change, this problem was much easier to find a solution to and get past. Once again, it was a simple matter of adding the right magic words to the Web.config:

<requestFiltering allowDoubleEscaping="true" />

Finally my Frankenstein was coming to life and I thought I was in the clear. But, then I realized that when other clients (not form POST-ers who would not realize my HttpModule was secretly processing their inputs) wanted to send me a URL with a forward slash in a path component they would have to double encode or use some other strange method to identify it as a different kind of forward slash then the normal path component delimiter.

So, I decided to add a feature to my framework that would allow a syntax to specify that “the rest” of a URL is a single component and to do that I wanted to use “/*”. Convinced I could use any character I wanted now, I went ahead and ran the debugger with my test path, and to my chagrin ran into this little beauty:

System.ArgumentException occurred
Message=Illegal characters in path.
at System.Security.Permissions.FileIOPermission.HasIllegalCharacters(String[] str)

mscorlib.dll!System.Security.Permissions.FileIOPermission.HasIllegalCharacters(string[] str) + 0x117 bytes
mscorlib.dll!System.Security.Permissions.FileIOPermission.AddPathList(System.Security.Permissions.FileIOPermissionAccess access, System.Security.AccessControl.AccessControlActions control, string[] pathListOrig, bool checkForDuplicates, bool needFullPath, bool copyPathList) + 0x4a bytes
mscorlib.dll!System.Security.Permissions.FileIOPermission.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess access, string[] pathList, bool checkForDuplicates, bool needFullPath) + 0x2c bytes
mscorlib.dll!System.IO.Path.GetFullPath(string path) + 0x5c bytes
System.Web.dll!System.Web.Util.FileUtil.IsSuspiciousPhysicalPath(string physicalPath, out bool pathTooLong) + 0x42 bytes
System.Web.dll!System.Web.Util.FileUtil.IsSuspiciousPhysicalPath(string physicalPath) + 0x18 bytes
System.Web.dll!System.Web.Util.FileUtil.CheckSuspiciousPhysicalPath(string physicalPath) + 0x9 bytes
System.Web.dll!System.Web.CachedPathData.GetPhysicalPath(System.Web.VirtualPath virtualPath) + 0x77 bytes
System.Web.dll!System.Web.CachedPathData.GetConfigPathData(string configPath) + 0x190 bytes
System.Web.dll!System.Web.CachedPathData.GetVirtualPathData(System.Web.VirtualPath virtualPath, bool permitPathsOutsideApp) + 0x6f bytes
System.Web.dll!System.Web.HttpContext.GetFilePathData() + 0x25 bytes
System.Web.dll!System.Web.HttpContext.GetConfigurationPathData() + 0x1b bytes
System.Web.dll!System.Web.Configuration.RuntimeConfig.GetConfig(System.Web.HttpContext context) + 0x2c bytes
System.Web.dll!System.Web.HttpContext.SetImpersonationEnabled() + 0xd bytes
System.Web.dll!System.Web.HttpApplication.AssignContext(System.Web.HttpContext context) + 0x5c bytes
System.Web.dll!System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest wr, System.Web.HttpContext context) + 0x22f bytes
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr managedHttpContext, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) + 0x1fc bytes
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr managedHttpContext, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) + 0x29 bytes
[Appdomain Transition]

So, in a last desperate attempt to not have to give up, I circled back to a solution that had not worked for any of the other problems I ran into before and to my surprise, it all worked out. Unfortunately, it requires adding a registry value, apparently making your entire server less secure and not an option except for in the most “all access” hosting environments. Anyway, you need to set the following to get the last few “illegal” characters to be allowed:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\VerificationCompatibility = 1 (32-bit DWORD)

Before I get accused of hacking my way out of this, this is actually a recommended fix from Microsoft written when this feature was first added as a service pack for .NET 1.1 but it is apparently still in there and for guys like me who like to push the limits, I thank them for trusting us a tiny bit:;EN-US;826437

I did find one posting that sort of talks about this problem (on Scott Hanselman’s blog) but it appears rather than finding a solution they opted to change their URLs to workaround the problem. Yes, maybe that was a better idea, but not nearly as FUN:

Hopefully this will help someone get past the issue themselves without all the forumining and experiments, or at least convince them it’s a bad idea and give up on the special characters. 😉

This entry was posted in Development, Web and tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.


  1. Posted August 5, 2015 at 12:01 pm | Permalink

    Thanks for the share!

  2. Posted August 19, 2015 at 7:10 am | Permalink

    WOW just what I was searching for. Came here by
    searching for and when done appropriately

  3. Martina
    Posted September 6, 2015 at 10:04 pm | Permalink

    nice game

  4. Posted September 7, 2015 at 9:02 am | Permalink

    Awesome things here. I am very glad to look your article.
    Thank you so much and I am taking a look ahead
    to contact you. Will you please drop me a mail?

  5. Posted September 25, 2015 at 1:14 am | Permalink

    ; これについて|スパム問題問題を持っていますか私もブロガーだ、と私はいた知りたいあなたの状況を、 私たちの多く開発しているいくつかの素晴らしい方法、私たちが見ているとスワップと 他の人 、興味を持っている場合|電子メールの電子メール私に撃つお願い。

  6. Posted September 29, 2015 at 8:10 am | Permalink

    ハウディ!私はこれがオフトピックちょっと知っているしかし私は考え出したのだ、私はお願いしたい。あなたがに興味があるトレーディングリンクまたは多分ゲスト書き込みポストをまたはその逆?マイ同じたくさんのサイトアドレストピックをあなたと私は信じと私たちは大いに相互に利益を得ることができる。あれば興味がシュートまでお気軽 。私はあなたからの聴取を楽しみにしています! 恐ろしい経由でブログ!

  7. b3tty
    Posted December 17, 2015 at 2:29 pm | Permalink

    Good stuff. Thank you.

  8. Posted December 28, 2015 at 2:21 pm | Permalink

    I have seen plenty of useful items on your site about computer systems. However, I have got the impression that laptops are still not nearly powerful sufficiently to be a option if you usually do things that require plenty of power, like video editing and enhancing. But for website surfing, microsoft word processing, and quite a few other common computer work they are perfectly, provided you cannot mind your little friend screen size. Thank you for sharing your ideas.

One Trackback

  • עבודה לצעירים באנגליה

    … עבודה בחול – כלומר, עבודה לצעירים באנגליה שתבחרו בעגלות המציעות מוצרים אליהם אתם מתחברים על מנת שלא לאבד הצפון. במקרה כזה חשוב להבהיר מראש את התנאים שמציע כל מעסיק. היכן ניתן לחסוך יותר? האם… Use any characters you want in your URLs with ASP.NET…

Post a Comment

Your email is never published nor shared. Required fields are marked *

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>