URL Routing, Image Handler & "A potentially dangerous Request.Path value" - asp.net

I've been experiencing this problem now for quite sometime and have decided to try and get to the bottom of it once and for all by posting the question here for some thought. I have an image handler in a .net 4 website located here:
https://www.amadeupurl.co.uk/ImageHandler.ashx?i=3604
(actual domain removed for privacy)
Now this works fine and serves an image from the web server without problem, I say without problem because if I access the URL it works fine, the image loads, no exception is generated. However someone did visit this exact URL yesterday and an exception was raised along the following lines:
Exception Generated
Error Message:
A potentially dangerous Request.Path value was detected from the client (?).
Stack Trace:
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig() at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
Technical Information:
DATE/TIME: 23/01/2013 03:50:01
PAGE: www.amadeupurl.co.uk/ImageHandler.ashx?i=3604
I understand the error message, thats not a problem I just don't understand why it being generated here, to make things worse I'm unable to replicate it, like I said I click the link the image loads, no exception. I am using URL routing and registered the handler to be ignored in case this was causing an issue with the following code:
routes.Ignore("{resource}.ashx")
I'm not sure why else I would be getting the error or what else to try.

Asp.Net 4.0+ comes with a very strict built-in request validation, part of it is the potential dangerous characters in the url which may be used in XSS attacks. Here are default invalid characters in the url :
< > * % & : \ ?
You can change this behavior in your config file:
<system.web>
<httpRuntime requestPathInvalidCharacters="<,>,*,%,&,:,\,?" />
</system.web>
Or get back to .Net 2.0 validation:
<system.web>
<httpRuntime requestValidationMode="2.0" />
</system.web>
A very common invalid character is %, so if by any chance (attack, web-crawlers, or just some non-standard browser) the url is being escaped you get this:
www.amadeupurl.co.uk/ImageHandler.ashx/%3Fi%3D3604
instead of this:
www.amadeupurl.co.uk/ImageHandler.ashx/?i=3604
Note that %3F is the escape character for ?. The character is considered invalid by Asp.Net request validator and throws an exception:
A potentially dangerous Request.Path value was detected from the client (?).
Though in the error message you see the unescaped version of the character (%3F) which is ? again
Here's a good article on Request Validation and how to deal with it

Even I faced this issue but for me, I accidentally typed & instead of the ? in the URL
for example:
example.com/123123&parameter1=value1&paameter2=value2
but in actual it has to be:
example.com/123123?parameter1=value1&paameter2=value2

A super old thread but this works:
return RedirectToAction("MyAction", new { #myParameterName = "MyParameterValue" });
You can also add the controller name after action name if the request is going to a different controller and also add more query string parameters simply by chaining them with commas between.

Related

Pipe Character in ASP.NET route parameter causing 404

We have a ASP.NET Web API method with the following route:
[System.Web.Http.Route( "api/MergeFields/{id}" )]
public virtual string Get( string id )
{
...
}
On most of our servers, if the {id} parameter in the url contains a pipe character, it will still match the route: http://www.example.com/api/MergeFields/Global|Test. However, we have one IIS server where this is returning a 404 error.
Encoding the pipe character does not help: http://www.example.com/api/MergeFields/GlobalAttribute%7CTest, it still returns a 404.
On that same server any other characters in the {id} parameter work fine. For example http://www.example.com/api/MergeFields/GlobalAttribute_Test works.
I have searched for anything in the web.config that might be affecting how a pipe character is interpreted by IIS or ASP.NET but have not been able to find anything. Again, it's just one server that is having this issue. On all our other installations the pipe character works fine and matches that route.
I am unable to comment, but I give it a shot as a solution.
Please let me know if it does not work.
Check the HttpRuntimeSection.RelaxedUrlToFileSystemMapping Property, it could be the issue.
Under your web.config you probably should set it up like this (.NET 4.0):
<system.web>
<httpRuntime requestValidationMode="2.0" relaxedUrlToFileSystemMapping="true"/>
</system.web>
I don't know about your enviroment, but I assume that you use 4.0.
Edit2:
Also read about the Request filtering (the service that probably is blocking the request). Good information and possible several other verbs you can use to "whitelist" your pipe character: https://learn.microsoft.com/en-us/iis/configuration/system.webserver/security/requestfiltering/
Edit:
FYI, the pipe is defined as a "unsafe character". I recommend to read this document regarding selection of separator characters: https://sites.google.com/site/getsnippet/javascript/ut/url-encoded-characters/-please-stop-using-unsafe-characters-in-urls

ASP.NET MVC, CustomErrors & ResponseRewrite

I have an MVC website (v5, though I don't think it's related) where I have intentionally introduced an error upon when attempting to establish a database connection (wrong server IP in the connection string). When the user hits the HomeController one dependencies for the constructor is a UserRepository (to get the current user profile data) which depends on a database connection/session to be available. When it's not, the Dependency Resolver can't inject the UserRepository and when that happens it causes an error (as it does with any dependency of any controller), and I get a generic "No parameterless constructor defined for this object". Which is pretty useless.
So I'm trying to use a custom error page to retrieve the inner exception and display it in a friendly manner. (Because this error is happening when trying to acquire the HomeController, it never actually reaches the HandleErrorAttribute, hence the relying on CustomErrors).
So I have an ErrorsController with a series of actions...
Snippet from ErrorsComtroller.cs
public ActionResult Error()
{
return View("Error_500");
}
public ActionResult NotFound()
{
return View("Error_404");
}
Snippet from web.config
<customErrors mode="On">
<error statusCode="404" redirect="~/errors/notfound" />
<error statusCode="500" redirect="~/errors/error" />
</customErrors>
The Error_500 page is pretty basic, it has a model type of HandleErrorInfo, but if it's not present it checks for Exception details using Server.GetLastError(). Problem is, GetLastError() is always null, and I get my custom error page but no additional details beyond my generic feedback of "An unexpected error has occured". After doing some digging I found that the method doesn't work after a redirect, which is the default way the CustomErrors functions. So I changed the web.config to use this line instead...
Snippet from web.config
This way it won't cause a redirect and the GetLastError() should have my exception details about the database connection problem. Thing is, now I get the default ASP.NET error page with this message.
An exception occurred while processing your request. Additionally,
another exception occurred while executing the custom error page for
the first exception. The request has been terminated.
So I did some more digging using intellitrace, and I see the exception about the database connection. A little farther down I see the error about not having a parameterless constructor on HomeController and then one about encountering an error trying to create the controller of type 'HomeController'. But then I see one that says
Error executing child request for /errors/error
So I navigated directly to that path and the page works fine. But when it's used in customerrors WITH the ResponseRewrite for the redirectmode, it errors out. I put a break line on the first (and only) line of the ErrorsController.Error() action, but it never gets hit. If I substitute the redirect path in the custom errors to a static file it works, but if I change it back to the ~/errors/error it fails again.
Is there a issue when using MVC actions as url's for the CustomErrors when ResponseRewrite is specified?
"This happens because "ResponseRewrite" mode uses Server.Transfer under the covers, which looks for a file on the file system. As a result you need to change the redirect path to a static file, for example to an .aspx or .html file:"
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx"/>
See: https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging
"Apparently, Server.Transfer is not compatible with MVC routes, therefore, if your error page is served by a controller action, Server.Transfer is going to look for /Error/Whatever, not find it on the file system, and return a generic 404 error page!"
See: CustomErrors does not work when setting redirectMode="ResponseRewrite"
In other words, you cannot use ResponseRewrite with views.
This is a well known issue that has been problematic for developers because it does not afford itself to either an easy or elegant solution. Bottom line, MVC does not play nice when using custom views for exception handling and customer user-friendly pages for HTTP errors. The stock error.cshtml file (i.e., a View) in the Views\Shared folder is a great thing to have because it maintains the layout of the web page and provides exception errors. But, when you get HTTP errors then you need to create a view to handle the status code errors (e.g., 404, 500, etc.). Note: if you go the route of sending HTTP errors to a view then the URL line will contain non-ideal info (see weblinks below for further explanation).
You could route HTTP errors to the Error view, but I don't recommend it because the Error view should be for application errors (i..e, exceptions) whereas a separate custom user-friendly page should be created for generic HTTP errors. The difference is that the former is an application problem that the site developer needs to look at whereas the latter is a user error (or at least should be) that does not require the developer to look at it (just my 2 cents).
An alternative is to bypass the views and use custom user-friendly pages for both application exceptions and HTTP errors. But, beware of two problems:
1.) The wrong status code is returned (usually 200), which can be a problem because it will be picked up and indexed by search engines (you do not want this!)
2.) The URL specifies a non-sensical URL in the web browser
These can be handled easy enough. See the following link (go down to the section customErrors in web.config): https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging
Below are other weblinks that I also found useful:
http://benfoster.io/blog/aspnet-mvc-custom-error-pages
https://msdn.microsoft.com/en-us/library/bb397417.aspx
https://www.youtube.com/watch?v=nNEjXCSnw6w
How do I display custom error pages in Asp.Net Mvc 3?
The last one appears to be yet another alternative: a custom hack to get around the problem of not being able to couple views with ResponseRewrite. This works by completely bypassing CustomErrors (i.e., CustomErrors mode="Off"). I have not yet tried this yet, but I am looking into it.
Final thought, keep an eye on all site status codes when either error or exception codes are thrown - make sure there are no 200 (i.e., OK) codes.

Strange Request URLs in logged ASP.NET exceptions, but not in IIS logs

Getting unhandled exception event log messages for legitimate exceptions but the event log message includes noise in the request URL.
The noise is injected where uri escaped characters are. Noise like the apppool name, "An unhandled exception has occurred.", False and sometimes the request url itself recursively injected, sometimes a dozen times inside the url. The IIS logs don't show this injection, just the original url.
Here's one of the recursive examples:
Request URL: http://domain.com/Page.aspx?q=bransonAn unhandled exception has occurred.Chttp://domain.com/Page.aspx?q=bransonAn unhandled exception has occurred.Chttp://domain.com/Page.aspx?q=bransonAn unhandled exception has occurred.Chttp://domain.com/Page.aspx?q=branson%2C%20momomomo
The one somewhat unusual thing about the code is that it uses an exception filter which does some logging and then returns false, allowing the exception to go unhandled.
I've encountered the same issue as described above and after a few days on Google have come up with the what caused it (well for me anyway) and thought that I'd share - Even though this discussion is over a year old.
It was caused by spaces being included in the query string, which were getting changed to %20. When an exception was getting raised within the code it appears that IIS (or the Development Server in Visual Studio 2008) was, possibly, assuming that the %20 was a parameter to be passed in to the exception handler and building up the crazy looking Request URL - It was always contained 82 times within the log and no where I searched mentioned this.
In the web.config the encoding can be managed through the globalization section, but this didn't resolve our issue - It turns out that if you use RFC2396, then you don't get this issue. We're now replacing our spaces with a non-breakable space character and this is working so far in our testing.

Why the double.Parse throw error in live server and how to track?

I build a website, that:
reads data from a website by HttpWebRequest
Sort all Data
Parse values of the data
and give out newly
On local server it works perfect, but when I push it to my live server, the double.Parse fails with an error.
So:
- how to track what the double.parse is trying to parse?
- how to debug live server?
Lang is ASP.Net / C#.net 2.0
You probably have culture issues.
Pass CultureInfo.InvariantCulture to double.Parse and see if it helps.
To see the exception on the server, add <customErrors mode="Off" /> to the <system.web> element in web.config. (And make sure to remove it afterwords)
Alternatively, you can setup a real error logging system, such as ELMAH, or check the server's event log.
Sounds like a problem with regional settings and the decimal separator. Might be different in your development/live servers.
I would use TryParse instead of just plain Parse. That way, you would control what is being intended to parse.
Like this.
double outval;
if (!double.TryParse(yourvar, out outval)) {
// throw and manage error on your website
}
// life goes on.

Problem with a URL that ends with %20

I have a big problem. There are devices in live that send the URL "/updates ". It's a typo of the developer for those devices. In the server logs, it looks like "/updates+".
I have a ManageURL rewriting module that handles all requests without extension. But this request causes an HttpException:
System.Web.HttpException:
System.Web.HttpException
at System.Web.Util.FileUtil.CheckSuspiciousPhysicalPath(String physicalPath)
at System.Web.HttpContext.ValidatePath()
at System.Web.HttpApplication.ValidatePathExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
As I see in the logs, the URL rewriting module does not even get this URL, so I cannot fix it there.
Is there a way to handle those URLs with ASP.NET?
Ok, this is an old thread, but I like to add a workable solution that works for all ASP.NET versions. Have a look at this answer in a related thread. It basically comes down to registering to the event PreSendRequestHeaders in global.asax.cs.
Alternatively, when on ASP.NET 4.0 or higher, use <httpRuntime relaxedUrlToFileSystemMapping="true" /> in web.config.
According to some, this is in System.Web.dll:
internal static void CheckSuspiciousPhysicalPath(string physicalPath)
{
if (((physicalPath != null) && (physicalPath.Length > 0))
&& (Path.GetFullPath(physicalPath) != physicalPath))
{
throw new HttpException(0x194, "");
}
}
I guess you cannot change that, but can't one disable it in the IIS settings? Of course, that would also disable all other checks... :-(
Or write some ISAPI filter that runs before the above code? Writing your own module is said to be easy, according to Handle URI hacking gracefully in ASP.NET.
Or, create your own error page. In this page (like suggested in the URI hacking link above) search for specific text in exception.TargetSite.Name, such as CheckSuspiciousPhysicalPath and if found (or simply always) look at current.Request.RawUrl or something like that, clear the error and redirect to a repaired URL?
you could run a URL-rewriting ISAPI, like IIRF.
If you have access to code why not just check for '+' at the end and remove it?

Resources