c# URL with plus sign not running through custom HttpModule - c#

I've got a custom HttpModule to redirect legacy URLs from an old build of the site which checks the incoming request URL against a database table of redirects.
However, when the incoming request URL contains a plus (+) sign, the request doesn't fall through the HttpModule - it works as expected for standard URLs.
For example, these URLs works:
http://www.example.com/sample-url
http://www.example.com/sample url
http://www.example.com/sample%20url
These don't:
http://www.example.com/sample+url
http://www.example.com/sample%2Burl
Here's my module declaration:
<add name="LegacyUrlHttpModule" type="Web.LegacyUrlHttpModule, Framework.Web" preCondition="managedHandler" />
Am I missing a setting here or something?

Scott Hanselmann wrote a nice blog post explaining how you could enable all kind of crap symbols in the Path portion of an url.
His conclusion is the following:
After ALL this effort to get crazy stuff in the Request Path, it's
worth mentioning that simply keeping the values as a part of the Query
String (remember WAY back at the beginning of this post?) is easier,
cleaner, more flexible, and more secure.
So basically if you have such characters in a url, those characters should be passed as query string parameters instead of attempting to pass them in the Path portion.

IIS rejects + in URLs by default. A workaround would be to allowDoubleEscaping
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
</system.webServer>
but beware that this may make your site more vulnerable to malicious URLs.

You can follow the below steps:
in the IIS webserver section, double click the 'Request Filtering' icon
in the 'File Name Extension' right click->Edit Feature Settings...' the file 'web.config'
check the option 'Allow double escaping' (this option is unchecked by default)
repeat all above 3 steps for the 'default website' (or whatever you have given the name to your site)
re-start the IIS

Related

How To Rewrite/Redirect url with . in path?

I have a site, which was built by asp.net 2 by another guy long time ago. For some reasons, google indexed lots of pages whose url has . in the path (not the domain part). i.e.
http://example.com/CA/Orange/Industrial-Warehouse-Space/1411-N.-St./1234567
In the code, UrlRewritingNet is used for rewriting url. One of the rule is:
<add name="Rewrite_5" virtualUrl="^~/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([0-9]+)/*$"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="~/Location.aspx?id=$5"
redirectMode = "Permanent"
ignoreCase="true" />
If the url is:
http://example.com/CA/Orange/Industrial-Warehouse-Space/1411-N.-St/1234567
Note that, no '.' after 'St'. Then the url will be rewritten successfully. But if used
http://example.com/CA/Orange/Industrial-Warehouse-Space/1411-N.-St./1234567
The site always shows:
Server Error in '/' Application
The resource cannot be found.
I'm wondering whether there is a way to rewrite/redirect this url to the correct url, or even homepage? Currently, it is on asp.net 2, if needed, can change to other framework too. Any suggestions?
Thanks
I'm using UrlRewritingNet for rewrite, not sure what the actual url it is trying to rewrite when the error happens. However, I can not capture this in the customError page for 404 (it is a 404 when look at the traffic).

DNN RewriterConfig redirection Rule

I try to redirect www.myDNNSite.com/hastinfo/[...] to http://172.16.244.43:83/[...] in DNN 7.x
To do that, I added a rule in SiteUrls.config as this blog showed https://bertcraven.wordpress.com/2008/05/21/quick-n-dirty-redirects-in-dotnetnuke/
<RewriterRule>
<LookFor>[^?]*/hastinfo/(.*)</LookFor>
<SendTo>http://172.16.244.43:83/$1</SendTo>
</RewriterRule>
This not work if there is a . after hastinfo, so:
www.myDNNSite.com/hastinfo/test -> OK 172.16.244.43:83/test
www.myDNNSite.com/hastinfo/myhandler.axd -> KO error 404 and no redirection
It seems that DNN make something with URL if there is a . founded.
How to make my redirection working even if a . (dot) is present in url ?
EDIT:
My objective with this redirection is to have the same end point for my dev and production environment. I have three server on the front end and the Web Service behind the www.myDNNSite.com/hastinfo point to three differents servers to load balance the charge.
Before update to DNN 7.X, I was using ManagedFusionRewriter that make the job.
But It is not updated from 2009 and now with IIS 8.5 I look a better way to make this redirection from a config file.
EDIT 2:
I try to add IIS Mod Rewrite in my IIS 8.5 and write in Web.config:
<rewrite>
<rules>
<rule name="Imported Rule 101" stopProcessing="true">
<match url="^hastinfo/(.*)" />
<action type="Rewrite" url="http://172.16.244.43:83/{R:1}" appendQueryString="true" />
</rule>
Without success ... here the Failed Tracing:
Using IIS Redirects in combination with the DNN Friendly Url providers is often a recipe for disaster sadly.
In this case, the reason that you are having issues more than likely is that the .axd is being captured by the ASP.NET process and that is preventing the re-writing from happening.
Based on what you are looking to do, can you explain a bit the true goal? The reason for this answer rather than a "do this" is that redirecting with DNN to a non-standard port is also going to cause issues as there is a setting for "usePortNumber" in the web.config that you will want to have on if using a non-standard port.
I finally found a way to make it works.
Thanks to: http://blogs.msdn.com/b/asiatech/archive/2011/08/25/return-404-4-not-found-when-url-rewrite.aspx
You need to install Application Request Routing and enable Proxy, then it will work with URL rewriting to remote servers (regardless where or what they are) since the Routing will take care of that.
http://www.iis.net/download/ApplicationRequestRouting

How to configure the web.config to allow requests of any length

I am building a site in which i would like to create a file client side from the value of a textarea element.
I have the code in place to do this, but i am getting this error
HTTP Error 404.15 - Not Found The request filtering module is
configured to deny a request where the query string is too long.
Is there a way to override this so that I am able to process requests of any size?
If not, is there a way to generate files client side without using the filesystem/active x object?
thanks
Add the following to your web.config:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxQueryString="32768"/>
</requestFiltering>
</security>
</system.webServer>
See:
http://www.iis.net/ConfigReference/system.webServer/security/requestFiltering/requestLimits
Updated to reflect comments.
requestLimits Element for requestFiltering [IIS Settings Schema]
You may have to add the following in your web.config as well
<system.web>
<httpRuntime maxQueryStringLength="32768" maxUrlLength="65536"/>
</system.web>
See: httpRuntime Element (ASP.NET Settings Schema)
Of course the numbers (32768 and 65536) in the config settings above are just examples. You don't have to use those exact values.
In my case ( Visual Studio 2012 / IIS Express / ASP.NET MVC 4 app / .Net Framework 4.5 ) what really worked after 30 minutes of trial and error was setting the maxQueryStringLength property in the <httpRuntime> tag:
<httpRuntime targetFramework="4.5" maxQueryStringLength="10240" enable="true" />
maxQueryStringLength defaults to 2048.
More about it here:
Expanding the Range of Allowable URLs
I tried setting it in <system.webServer> as #MattVarblow suggests, but it didn't work... and this is because I'm using IIS Express (based on IIS 8) on my dev machine with Windows 8.
When I deployed my app to the production environment (Windows Server 2008 R2 with IIS 7), IE 10 started returning 404 errors in AJAX requests with long query strings. Then I thought that the problem was related to the query string and tried #MattVarblow's answer. It just worked on IIS 7. :)
If you run into this issue when running an IIS 8.5 web server you can use the following method.
First, find the "Request Filtering" module in the IIS site you are working on, then double click it...
Next, you need to right click in the white area shown below then click the context menu option called "Edit Feature Settings".
Then the last thing to do is change the "Maximum query string (Bytes)" value from 2048 to something more appropriate such as 5000 for your needs.
Something else to check: if your site is using MVC, this can happen if you added [Authorize] to your login controller class. It can't access the login method because it's not authorized so it redirects to the login method --> boom.
It will also generate error when you pass large string in ajax call parameter.
so for that alway use type post in ajax will resolve your issue 100% and no need to set the length in web.config.
// var UserId= array of 1000 userids
$.ajax({
global: false,
url: SitePath + "/User/getAussizzMembersData",
"data": { UserIds: UserId},
"type": "POST",
"dataType": "JSON"
}}
I had a similar issue trying to deploy an ASP Web Application to IIS 8. To fix it I did as Matt and Leniel suggested above. But also had to configure the Authentication setting of my site to enable Anonymous Authentication. And that Worked for me.
I had to add [AllowAnonymous] to the ActionResult functions in my login page because the user was not authenticated yet.
If your website is using authentication, but you don't have the correct authentication method set up in IIS (e.g. Basic, Forms etc..) then the browser will be getting stuck in a redirect loop. This causes the redirect url to get longer and longer until it explodes.
For someone who experiences this while running the apps from Visual Studio, while using IIS Express, first you have to locate the applicationhost.config file being used by the application. See the answer at https://stackoverflow.com/a/41553876/1849880 on how to locate the applicationhost.config file. Then, you can change the maxQueryString value as explained above.
HTTP Error 404.15 - Not Found The request filtering module is
configured to deny a request where the query string is too long.
To resolve this problem, check in the source code whether the Form tag has a property method is get/set state.
If so, the method property should be removed.

Is Enabling Double Escaping Dangerous?

I have an ASP.NET MVC application with a route that allows searching for stuff via /search/<searchterm>.
When I supply "search/abc" it works well, but when I supply "/search/a+b+c" (correctly url encoded) then IIS7 rejects the request with HTTP Error 404.11 (The request filtering module is configured to deny a request that contains a double escape sequence). FIrst of all, why does it do this? It only seems to throw the error if it is part of the URL, but not as part of a query string ( /transmit?q=a+b+c works fine).
Now I could enable double escape requests in the security section of my web.config but I'm hesitant to do so as I don't understand the implications, and neither why the server would reject the request "a+b+c" as part of the URL but accept as part of a query string.
Can someone explain and give some advice what to do?
Edit: Added emphasis to relevant sections.
Basically: IIS is being excessively paranoid. You can safely disable this check if you're not doing anything particularly unwise with the uri decoded data (such as generating local filesystem URI's via string concatenation).
To disable the check do the following (from here): (see my comment below for what double escaping entails).
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true"/>
</security>
</system.webServer>
If the plus symbol is a valid character in a search input, you will need to enable "allowDoubleEscaping" to permit IIS to process such input from the URI's path.
Finally, a very simple, if limited workaround is simply to avoid '+' and use '%20' instead. In any case, using the '+' symbol to encode a space is not valid url encoding, but specific to a limited set of protocols and probably widely supported for backwards-compatibility reasons. If only for canonicalization purposes, you're better off encoding spaces as '%20' anyhow; and this nicely sidesteps the IIS7 issue (which can still crop up for other sequences, such as %25ab.)
I would just like to add some information to Eamon Nerbonne's answer related to the "what to do" part of your question (not explaining the whys).
You can easily change a particular application's settings too with
opening the console with admin rights (Start - cmd - right click, Run as administrator)
typing in the following (taken from here: http://blogs.iis.net/thomad/archive/2007/12/17/iis7-rejecting-urls-containing.aspx):
%windir%\system32\inetsrv\appcmd set config "YOURSITENAME" -section:system.webServer/security/requestfiltering -allowDoubleEscaping:true
(you can e.g. substitute YOURSITENAME with Default Web Site for applying this rule to the default website)
Enter, ready.
An example:
firstly I had the same problem:
Typing in the text mentioned above:
Now it works as expected:
Have you thought about having the search URL like '/search/a/b/c'?
You'd need to setup a route like
search/{*path}
And then extract the search values from your path string in the action.
I ran into this under IIS 7.5 doing a Server.TransferRequest() in an application.
Encoding the filename caused the double-escape problem, but if I didn't encode it then I'd run into the "potentially dangerous Request.Path" error.
Putting an any protocol, even an empty one, on the URL I pass to Server.TranferRequest() fixed the problem.
Does not work:
context.Server.TransferRequest("/application_name/folder/bar%20bar.jpg");
Works:
context.Server.TransferRequest("://folder/bar%20bar.jpg");

IIS URL Rewriting: How can I reliably keep relative paths when serving multiple files?

My WebApp is part CMS, and when I serve up an HTML page to the user it typically contains relative paths in a.href and img.src attributes.
I currently have them accessed by urls like: ~/get-data.aspx/instance/user/page.html -- where instance indicates the particular instance for the report and "user/page.html" is a path created by an external application that generates the content.
This works pretty reliably with code in the application's BeginRequest method that translates the text after ".aspx" into a query string, then uses Context.RewritePath().
So far so good, but I've just tripped over something that took me by surprise: it appears that if any of the query string ("instance/user/page.html") happens to contain a plus sign ("+") the BeginRequest method is never called, and a 404 is immediately returned to the user.
So my question is two-fold:
Am I correct in my belief that a "+" would cause the 404, and if so are there other things that could cause similar problems? Is there a way around that problem (perhaps a different method than BeginRequest)?
Is there a better way to preserve relative URL paths for generated content than what I'm using? I'd rather not require site admins to install a 3rd party rewrite tool if I can help it.
Yes this is an IIS security setting. You can get round it by putting this in your web config.
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="True"/>
</security>
</system.webServer>
However youmight have to be carefull what you are doing. With double escaping enabled it will allow an escaped url to itself contain escape characters that could be used to exploit your url rewriting to pass escaped characters into your querystring to construct a different querystring than you intend.

Categories

Resources