ASP.NET whitespace or %20 in URL - asp.net

Good day, everyone.
I found strange behavior within ASP.NET engine when it handles non-existent URL with whitespace.
When we have normal URL like this one: https://stackoverflow.com/questions/tagged1/c%23
we get normal custom 404 page as was intended by developers (if any).
But here's the bug. Just add some white space like this:https://stackoverflow.com/questions/tagged /c%23
and you'll see nasty ASP.NET 404 error page. Whether such a page should ever be displayed is another story. I've already made some heavy googling, made debugging research, and I can say that in this situation all custom handlers are ignored, global application class (Application_Error in global.asax) are just not reached. Actually, I don't see how can this situation be handled by ASP.NET. Any ideas?
Just as a note, this behavior is related to ASP.NET and ASP.NET MVC (as show on StackOverflow.com example). I tried other sites and found that even Microsoft.com falls into this category (see this: http://www.microsoft.com/en/us%20/default.aspx). Also, we can replace whitespace with %20 sequence with no better result.

Workaround is found.
HttpException is thrown with 'Error executing child request for pageName.aspx' message.
First of all, ASP.NET can't find requested page or route. Then exception is thrown from System.Web.CachedPathData.GetVirtualPathData (actually, from System.Web.CachedPathData.GetConfigPathData, but GetVirtualPathData makes things clear).
Then if we have any error handler, it provides some actions and tries to do something. Here we usually have Server.Transfer or Request.Redirect that moves user to page 404 or more common error page. But. In current situation HttpException is thrown anyway and we get ASP.NET error page. And in this situation Server.ClearError and Server.RewritePath can help: exception is not thrown this way. BUT! Such error handling crashes normal business logic exceptions thrown by our application.
And to resolve new trouble we have to use if/else depending on whether we receive HttpException (so we use ServerRewrite with ClearError) or some exception from our own code. But again, that's good if you provide your own exception classes, but what if not...
Anyway, I consider this a very strange case, especially that Application_Error handler is ignored whilst other application code is still executed.
Edit
As code-way was not the best selection (we can only guess that we have THIS error when exception Message is empty and InnerException is null) the better solution lies within ISAPI rewriter with rule like (\s+(\.aspx).*)|(\s+/) to custom 404 page. Here we catch all requests like /somePage .aspx and /somePath /. When we have whitespace not preceding .aspx or slash but within page name or path part we don't have mentioned problem.

Isn't it just that the request never reaches the asp.net pipeline. If you set up error documents in IIS, wouldn't they be displayed instead of the "nasty page" ?

Related

"potentially dangerous Request.Path value" caused by ampersand (that shouldn't be there)

I am working on an ASP.NET website. The website's users are sent an email with a link to the site. The link will look something like this:
https://<website>/Default.aspx?LC=<guid>
where the "LC" parameter is their login code. The "LC" parameter is the only parameter we ever put on the link. It's also possible to go directly to the Default.aspx page without a code and type one in at the prompt.
Here's the problem: on rare occasions (but consistently since the site launched), I've been getting an error report from the Global.asax handler that says:
12:24:41 ERROR Global.asax - Application_Error - unhandled error:
System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (&).
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
I have no idea why I keep getting these messages. I've tried logging HttpContext.Current.Request.RawUrl to see the actual URL the client is using, but all I ever get is this:
/&
and HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath reports as:
~/&
Is there some way I can log the "real" request and see where this ampersand is coming from? The LC parameter value is always a GUID so it would never have an ampersand in it. Also, this problem does not seem to happen for 99% of the site users. For all I know this is being caused by a bot or something, but if it's happening to real users I'd like to find out why.

AJAX Callbacks Allowing HTML

I have a comment form on my website and I would like to stop any HTML from being posted through it. I was under the impression that ASP.NET automatically stops any HTML from being submitted by throwing a "potentially dangerous request" exception, but it's allowing HTML in this case.
All of the settings that relate to validation have been left to default so it should be set to requestValidationMode="4.0".
Anyone know what can cause this? Does it have anything to do with the fact that I am using AJAX callbacks?
Edit: I have gathered some more details:
Validation is correctly working in one sub-folder in my application, but it isn't working in any of the others. I looked into my web.config and this is the only setting I have put regarding page validation:
<pages enableViewStateMac="true" validateRequest="true">
Why is it working in one subfolder but not in the others? Does it have anything to do with the fact that this subfolder has a web.config entry regarding authentication?
Edit: Regular postbacks are being validated, just not callbacks.
Edit again: I was playing around with Fiddler and while doing so I noticed one of the callbacks was blocked by the server. Here is what the blocked request looks like:
And here is the plain text version:
__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUKLTI4MDgzMDI5NA9kFgJmD2QWBAIBDxYCHgdwcm9maWxlBSFodHRwOi8vd3d3LnczLm9yZy8yMDA1LzEwL3Byb2ZpbGVkAgMPZBYOZg8WAh4Fc3R5bGUFkAFiYWNrZ3JvdW5kLXBvc2l0aW9uOnJpZ2h0IGJvdHRvbTtiYWNrZ3JvdW5kLXJlcGVhdDpOby1SZXBlYXQ7YmFja2dyb3VuZC1pbWFnZTp1cmwoaHR0cDovL2xvY2FsaG9zdDo4MS9JbWFnZXMvTGF5b3V0LUltYWdlcy9UaXRsZUJhY2tncm91bmQucG5nKTtkAgIPFgIeCWlubmVyaHRtbAWlAjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48IS0tCmdvb2dsZV9hZF9jbGllbnQgPSAiY2EtcHViLTk2MTM2OTA0OTA1Mjg4MTQiOwovKiBCT0lHIFRvcCAqLwpnb29nbGVfYWRfc2xvdCA9ICI0MjcwOTc3NjY2IjsKZ29vZ2xlX2FkX3dpZHRoID0gNzI4Owpnb29nbGVfYWRfaGVpZ2h0ID0gMTU7Ci8vLS0%2BCjwvc2NyaXB0Pgo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIKc3JjPSJodHRwOi8vcGFnZWFkMi5nb29nbGVzeW5kaWNhdGlvbi5jb20vcGFnZWFkL3Nob3dfYWRzLmpzIj4KPC9zY3JpcHQ%2BZAIDDxYCHwIFqgI8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI%2BPCEtLQpnb29nbGVfYWRfY2xpZW50ID0gImNhLXB1Yi05NjEzNjkwNDkwNTI4ODE0IjsKLyogQk9JRyBTaWRlYmFyICovCmdvb2dsZV9hZF9zbG90ID0gIjIyMDAxMDYxMTAiOwpnb29nbGVfYWRfd2lkdGggPSAxNjA7Cmdvb2dsZV9hZF9oZWlnaHQgPSA2MDA7Ci8vLS0%2BCjwvc2NyaXB0Pgo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIKc3JjPSJodHRwOi8vcGFnZWFkMi5nb29nbGVzeW5kaWNhdGlvbi5jb20vcGFnZWFkL3Nob3dfYWRzLmpzIj4KPC9zY3JpcHQ%2BZAIEDw8WAh4HVmlzaWJsZWdkZAIFDxYCHwIFEjxwPkxpbmsgMSB0ZXh0PC9wPmQCBg9kFgICAw8WAh8DaGQCBw8WAh4EVGV4dAU%2BPHNwYW4gc3R5bGU9Im1hcmdpbi1yaWdodDogNXB4OyI%2BwqkgQmluZGluZ09mSXNhYWNHdWlkZTwvc3Bhbj5kZKMbP1fMlxWhgVw8zpEPBPGzlw5j&=sdfdsgd%40sfds.com&=%3Cp%3Efghfghfg%3C%2Fp%3E&=%3Cp%3Efghfghfg%3C%2Fp%3E&=%3Cp%3Efghfghfg%3C%2Fp%3E&__CALLBACKID=__Page&__CALLBACKPARAM=sdfdsgd%40sfds.com--%7C%7C--%3Cp%3Efghfghfg%3C%2Fp%3E--%7C%7C--%3Cp%3Efghfghfg%3C%2Fp%3E--%7C%7C--%3Cp%3Efghfghfg%3C%2Fp%3E
Here is a typical request that isn't blocked:
Plain text:
__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUKLTI4MDgzMDI5NA9kFgJmD2QWBAIBDxYCHgdwcm9maWxlBSFodHRwOi8vd3d3LnczLm9yZy8yMDA1LzEwL3Byb2ZpbGVkAgMPZBYOZg8WAh4Fc3R5bGUFkAFiYWNrZ3JvdW5kLXBvc2l0aW9uOnJpZ2h0IGJvdHRvbTtiYWNrZ3JvdW5kLXJlcGVhdDpOby1SZXBlYXQ7YmFja2dyb3VuZC1pbWFnZTp1cmwoaHR0cDovL2xvY2FsaG9zdDo4MS9JbWFnZXMvTGF5b3V0LUltYWdlcy9UaXRsZUJhY2tncm91bmQucG5nKTtkAgIPFgIeCWlubmVyaHRtbAWlAjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij48IS0tCmdvb2dsZV9hZF9jbGllbnQgPSAiY2EtcHViLTk2MTM2OTA0OTA1Mjg4MTQiOwovKiBCT0lHIFRvcCAqLwpnb29nbGVfYWRfc2xvdCA9ICI0MjcwOTc3NjY2IjsKZ29vZ2xlX2FkX3dpZHRoID0gNzI4Owpnb29nbGVfYWRfaGVpZ2h0ID0gMTU7Ci8vLS0%2BCjwvc2NyaXB0Pgo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIKc3JjPSJodHRwOi8vcGFnZWFkMi5nb29nbGVzeW5kaWNhdGlvbi5jb20vcGFnZWFkL3Nob3dfYWRzLmpzIj4KPC9zY3JpcHQ%2BZAIDDxYCHwIFqgI8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI%2BPCEtLQpnb29nbGVfYWRfY2xpZW50ID0gImNhLXB1Yi05NjEzNjkwNDkwNTI4ODE0IjsKLyogQk9JRyBTaWRlYmFyICovCmdvb2dsZV9hZF9zbG90ID0gIjIyMDAxMDYxMTAiOwpnb29nbGVfYWRfd2lkdGggPSAxNjA7Cmdvb2dsZV9hZF9oZWlnaHQgPSA2MDA7Ci8vLS0%2BCjwvc2NyaXB0Pgo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIKc3JjPSJodHRwOi8vcGFnZWFkMi5nb29nbGVzeW5kaWNhdGlvbi5jb20vcGFnZWFkL3Nob3dfYWRzLmpzIj4KPC9zY3JpcHQ%2BZAIEDw8WAh4HVmlzaWJsZWdkZAIFDxYCHwIFEjxwPkxpbmsgNSB0ZXh0PC9wPmQCBg9kFgICAw8WAh8DaGQCBw8WAh4EVGV4dAU%2BPHNwYW4gc3R5bGU9Im1hcmdpbi1yaWdodDogNXB4OyI%2BwqkgQmluZGluZ09mSXNhYWNHdWlkZTwvc3Bhbj5kZCu6t45MzsFLBRWYDAvPXYbIXKqE&=&=&=&=&__CALLBACKID=__Page&__CALLBACKPARAM=cfdsdg%40adfds.com--%7C%7C--%3Cp%3Esdfdgdfg%3C%2Fp%3E--%7C%7C--%3Cp%3Esdfdgdfg%3C%2Fp%3E--%7C%7C--%3Cp%3Esdfdgdfg%3C%2Fp%3E
I don't know why the requests are different, nothing changed on the page. I noticed that the first one seems to have split the parameters into the boxes while the second one hasn't. Is this the issue?
I just checked the callbacks being sent from the sub-folder and they are all split into parameters just like the first request. I guess this is the problem... but why is it happening?
I made the inputs runat=server and the request changed a bit, but the values are still not being assigned.
Here is what I found:
___CALLBACKPARAM is not actually validated by the server, only the parameters as seen in the first image are. With this in mind I validated the request myself using the following regex <\/*(p|div|span|a|script|br|b|i|u|h1|h2|h3|ol|ul|li)\s*.*>. You can find more online; hope this helps.

ASP.Net. Why am I not seeing my defaultRedirect page even when customErrors mode="On"

Here's the situation: -
I have
<customErrors mode="On" defaultRedirect="error.html" />
in my web.config.
I also have custom error handling code in Application_Error (in global.asax.cs) that checks for certain well known exception types and redirects to custom error pages for each. If the exception is not a well known type then I simple return from Application_Error without calling Server.ClearError() so the default custom handling should take care of showing the page error.html.
But whenever my app throws up an unhandled (and not well known) exception I end up at the default Asp.Net error page - you know the one I mean, the yellow screen of death...
Runtime Error
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed.
Details: To enable the details of this specific error message to be viewable on the local server machine, please create a tag within a "web.config" configuration file located in the root directory of the current web application. This tag should then have its "mode" attribute set to "RemoteOnly". To enable the details to be viewable on remote machines, please set "mode" to "Off".
I have checked the obvious stuff (like double checking that I am not throwing another error in Application_Error and I am not accidently' calling ClearError. It is definitely something fishy with this one web app (I made a little test web app and the custom error handling worked as expected) - that should rule out oddities in my machine.config file.
I am going to keep on scratching my head and trying things but in the meantime I thought I would put the question out here to see if anyone had any bright ideas.
PS. I am working on Windows 7 Business (IIS 7.5) but the same behavior is observed on Win server 2003 (IIS6).
Thanks Joe and Click for having a look but this problem is all my fault!
One crucial bit of information that I omitted from the description is that my web page flushes the response before the request is finished (see * below if you want to know why I do this nastiness).
It seems that once some content has been sent to the client, the customError handling no longer works. I can't say that this is a failing of the custom error handling because it would probably take some dark voodoo to tell a browser to redirect to once it had started rendering content!
Having said that I was hopeful that adding redirectMode="ResponseRewrite" to the customError node would help (maybe get the error page below the content I have already sent to the browser?) but that fails too. Nevermind.
A quick google yields this http://forums.iis.net/p/993221/1313916.aspx - and a chap on there has a work around that I will try. The technique suggested in http://forums.iis.net/p/993221/1399583.aspx#1399583 works. It is far from ideal (we have to read the web config) but it works.
(*) why am I flushing the response before the request is finished? Some of our pages return large reports which can take several seconds to generate. We send a "PLease wait + spinny gif" message to the clients at the start of these requests and flush that so that the browser renders the message + icon whilst it waits for the rest of the response. I think I shall investigate a less "hacky" way of achieving this.

How to stop a 500 .net error created calling the 500 error page

Here's an interesting one for you.
I've got my custom 500.aspx setup which is called when a 500 error occurs in my application. The 500.aspx also sends me an email with the error details.
I've noticed one small problem.
If you attempt an xss attack on the 500.aspx itself, the 500 page is not called.
This is obviously some sort of logic issue.
In fact, microsoft themselves suffer from the same issue.
See it in action here
http://www.microsoft.com/500.aspx?aspxerrorpath=%3Cscript%3Ealert(%22XSS%22)%3C/script%3E
How can I prevent this?
Ed
If you attempt an xss attack on any page, the custom error page will not be called (here's another random page on Microsoft.com with xss in the querystring).
The behavior appears to be intentional to stop the attack dead in its tracks. Even the error message indicates this behavior:
Request Validation has detected a
potentially dangerous client input
value, and processing of the request
has been aborted.
The only workaround appears to be to disable validation or to capture and handle the error in your global on Application_Error.
It appears that once you define a page to handle specific(or non specific?) errors, it is no longer available directly via its url, sorta like the Web.Config cant be called via the browser.
I would set up a 500Test.aspx which throws an exception causing a 500 error (and thus fires the 500.aspx)
That might work.
You might want to think about handling your errors in the Application_Error event in Global.asax.cs instead of the 500.aspx page. You could put the email code there, then redirect the user to an error page after you've done your error handling (this is how we do it where I work).

WebResource.axd requested without parameters - This is an invalid webresource request

I'm finding this problem every now and then in my production website, and it has me absolutely stumped...
My app works perfectly in both dev and production, but every now and then, I get an e-mail from my global error handling with this:
MESSAGE: This is an invalid webresource request.
URL: /WebResource.axd
(which means that for some reason webresource.axd was requested without specifying any GET parameters)
I'm not doing anything with webresource.axd myself, I don't get any of my resources through it, it's only used automatically by .Net to serve it's typical JS for validators, etc.
Any idea why this might be getting requested without parameters?
Has anyone encountered this?
That definitely is a bot not doing very good job of crawling your web site. It processes your web form and locates reference to WebResource.axd, for example:
<script src="/site/WebResource.axd?d=MtIW_TBRtZCvAXDMJGwg4g2&t=633772897740666651" type="text/javascript"></script>
The bot expects static JavaScript files only and tries to download it by requesting WebResource.axd without parameters. The result is an exception thrown by System.Web.Handlers.AssemblyResourceLoader class and intercepted by Application_Error in Global.asax.
I believe this exception is harmless - the client will receive 404 error. You can safely ignore it.
We also have all of our errors emailed to us, and we occasionally get those too. They never seem to have a referrer, and the user agent is usually a little wacky. We write them off as bots.
I just checked a couple of the offending client IP's against Arin, and one them belonged to a web-spidering-type organization, so there's a little more evidence for the bot theory.
I would also log the useragent that made the request to WebResource.axd. It wouldn't surprise me if it was a bot crawling your site.
This discussion...
http://www.telerik.com/community/forums/aspnet/spell/this-is-an-invalid-webresource-request.aspx
... and this linked MSDN article...
http://msdn.microsoft.com/en-us/magazine/cc163708.aspx
... might shed a little light (though not much).

Resources