Pipe Character in ASP.NET route parameter causing 404 - asp.net

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

Related

Change "returnUrl" before redirect in Controller

I have the implementation of authentication using "returnUrl" on the URL to redirect users after they login to the system. For some special cases of business logic, I need to replace some parts in value of "returnUrl" on the URL:
Character "/" to be replaced with "_1_"
Character "&" to be replaced with "_2_"
Character "+" to be replaced with "_3_"
So, with the returnUrl=/product/detail/xxx+abc&xyz, the final value of returnUrl is "_1_product_1_detail_1_xxx_3_abc_2_xyz"
In the controller, I replace the "_1_", "_2_", "_3_" to the according characters as above. After calling "return Redirect("/product/detail/xxx+abc&xyz")", the browser redirects to "_1_product_1_detail_1_xxx_3_abc_2_xyz" that is completely wrong. I'm not sure why its not working although the URL I pass to Redirect(URL) method is correct. May anyone give me some advises?
The information of .NET:
.NET Framework 4.7.1
System.Web.Mvc 5.2.4
Thank you.

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

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.

HttpHandler to download txt files (ASP.NET)?

Hey, I created a HttpHandler for downloading files from the server. It seems it is not handling anything...I put a breakpoint in the ProcessRequest, it never goes there.
public class DownloadHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//download stuff and break point
}
}
It never stops there, as mentioned. I also registered it in the web.config.
<add verb="*" path="????" type="DownloadHandler" />
I am not sure about the path part of that entry. What do I have to enter there? I am downloading txt files, but the URL does not contain the filename, I somehow have to pass it to the handler. How would I do this? Session maybe?
Thanks
Have you read How to register Http Handlers? Are you using IIS 6 or 7?
The path part should contain a (partial) url, so if in your case you are using a static url without the filenames, you should put that there. You can end the url in the name of a non-existent resource and map that to path
e.g. the url is http://myserver.com/pages/downloadfiles
and the path="downloadfiles"
If you do POST, you can put the filename in a hidden field, and extract it in the handler. If you're using GET, I'm not sure, either cross-post the viewstate or put the filename in the session like you said.
Any reason why you can't put the filename in the url?
The path for a handler needs to be the path you are trying to handle - bit of a tautology I know but it's as simple as that. Whatever path on your site (real or much more likely virtual) you want to be handled by this handler.
Now unless the kind of file at the end of that path is normally handled by ASP.NET (e.g. .aspx, .asmx but not a .txt) ASP will never see the request in order for it to go through it's pipeline and end up at your handler. In that case you have to bind the extension type in IIS to ASP.NET.
As far as identifying what file the handler is supposed to respond with you could achieve this any number of ways - I would strongly recommend avoiding session or cookies or anything temporal and implicit. I would instead suggest using the querystring or form values, basically anything which will show up as a request header.
Fianlly, I have to ask why you're using a handler for this at all - .txt will serve just fine normally so what additional feature are you trying to implement here? There might well be a better way.

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.

ASP.NET and the Output Cache - how can see if it's working?

Problem: I've got an ASP.NET website and i don't believe that my code is getting OutputCached correctly. I'm using IIS7 performance counters to show me the hits or misses a second.
i've got a simple ASP.NET MVC website. I'm using the built in ASP.NET Output Cache magic.
Here's some sample code :-
[AcceptVerbs(HttpVerbs.Get)]
[ApiAuthorize] // <-- this checks the querystring for a "key=1234".
// Doesn't find it, then it throws a 401 NOT AUTH exception.
[OutputCache(CacheProfile = "HomeController_Foo")]
public ActionResult Foo(string name, byte? alpha, byte? beta)
{
}
so this means that each url query can be like the following :-
http://www.mydomain.com/Foo?name=hello+word&key=1234
http://www.mydomain.com/Foo?name=hello+word&alpha=1&key=1234
http://www.mydomain.com/Foo?name=hello+word&alpha=1&beta=2&key=1234
Now, notice how i've got the OutputCache referencing a config file? here it is...
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="HomeController_Foo" duration="3600" varyByParam="key;name;alpha;beta"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
Nothing too hard ...
so here's the kicker! When I confirm that this is happening by using the IIS7 performance counters, it's saying that the output cache misses/sec are 100% of the requests i'm making a sec. Output cache hits are 0/sec.
I'm using a 3rd party web load stress testing program to bast my site with queries. Now, what's the source data? a list of names. The program keeps looping through all the names, then goes back to the start, rinse repeat. So it's BOUND to call the same query string at least once. IIS log files confirm this.
I'm not passing in any data for the alpha or beta.
this is my query string i'm hitting....
http://www.mydomain.com/Foo?name=hello+word&key=1234
... where i keep substituting the 'hello+world' with the names from the data source file and IIS logs confirm this.
So .. am i looking at the wrong performance counter? Are there any other tricks to see if it's getting outputcached? The code is very fast, so it's hard to tell if that is a cached result or not.
Probably way too late but to help others : If you had a cookie in your response header, that will prevent it from being cached. The outputcache (http) module has a lot of silent check to ensure the response is subject to being cached. Looking into it through reflection might give anyone candidate of failure to put in cache.
Use a tool like firebug and look at the response from the request. You'll be able to tell by the 200 or 304 whether the cache response was used (304) or if a successful response was sent (200).

Resources