Prevent trailing slash which included at the end of the URL - iis

From a security perspective there is need be to disable directory browsing for us, however we have been disabled this feature from the IIS, but it redirects directory requests with 301 (move permanent) by adding trailing slash at the end of the URL.
In this way hackers may aware of directories and sub-directories locations which we don't like it!
How do prevent adding trailing slash at the end of the URL for existing directories?

I solved it by using HttpApplication.BeginRequest Event . when a request for a directory arrived, checking directory existence in location of given Request.PhysicalPath specifies that the request is for directory or not.
I share the code, maybe helps someone:
public void OnApplicationBeginRequest(HttpApplication app)
{
if (app.Request.CurrentExecutionFilePath!="/"&& System.IO.Directory.Exists(app.Request.PhysicalPath))
{
app.Response.StatusCode = 404;
app.CompleteRequest();
}
}
However this worked for me perfectly but perhaps there is a better solution using IIS modules which I'm so excited to know. :)

Related

Use .htaccess to allow subfolders both with and without trailing slash

I am about to move my html files from the root folder to a couple of subfolders.
The default setting my host is using is to show the trailing slash for the subfolders and no slash for the html files. If the browser requests a subfolder without trailing slash, a 301 redirect to the same folder with trailing slash is returned. The files are shown without html extension thanks to a .htaccess snippet.
I think I like the approach to distinguish the subfolders from the files. In my case the contents of the index files will be different than the ordinary files.
However, I am not as convinced as many others that duplicate content is a disaster. I cannot be sure how my websites will develop in the future and what I will think about trailing slashes and such, so an easy forward compatible strategy is therefore desirable. For that reason I am considering to abandon the 301 redirect and instead allow the browser to send urls to subfolders both with and without the trailing slash and with response 200 OK in both cases. Yes, that leads to duplicate content, but I will will keep the trailing slash on all subfolders on all internal and canonical links, so in practice, I do not think it is a disaster. And Google and Bing and others should be able to figure things out.
I have my sites on a shared server configured via directadmin and (probably) no access to other configuration files and do not know how the default setting has been accomplished. I guess I need to do something in .htaccess to change the default setting but I am not sure what.
Is there anybody who knows how to override the default setting so that I get rid of the 301 redirect in the mentioned case and instead send 200?
I found this interesting document https://httpd.apache.org/docs/2.4/mod/mod_dir.html#directoryindex , but I can not interpret it, and I do not dare to do any trial and error. Hope that somebody can give me a hint.

Redirect urls with trailing slash

My website currently online is completely static and all the URLs have a trailing slash at the end : https://www.website.com/blog/article-1/
I'm working on my new website which is using Prestashop. On Prestashop, URLs don't have a trailing slash : https://www.website.com/blog/article-1
Problem: I have an excellent SEO on my current website and I need to keep the actual URLs (with trailing slash) available. For user experience, I'd like URLs to work with or without trailing slash.
How can I redirect my new URLs to the same URL + trailing slash? If possible, I'd like to rewrite URLs so that users always see the URL with a trailing slash.
Example :
https://www.website.com/blog/article-1/ is redirected to https://www.website.com/blog/article-1 and the URL visible in the address bar is https://www.website.com/blog/article-1/.
Well, ask "How can I redirect my new URLs to the same URL + trailing slash"...
The answer obviously is: by implementing exactly that rule. There are thousands of examples for this alone here on SO. None of those helped? Why not?
Anyway, here is another one:
RewriteEngine on
RewriteRule ^/blog/([^/]+)$ /blog/$1/ [R=301]
RewriteRule ^/blog/([^/]+)/$ /blog/$1 [END]
You need to take care to send out references with leading slashes with this setup. Since otherwise your site will be dead slow, since the clients will have to request every single page twice due to the redirection then required for every single page...
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).
If you mean default prestashop links like products, categories etc. you can just change their way to be built. Prestsahop allows us to achieve this within admin-panel Configure->Shop Parameters->Traffic & SEO->SEO and URL's>Schema of URLs (for PS 1.7).
And there change an URL in interest, for example, Route to category
from {id}-{rewrite} to {id}-{rewrite}/. And you won't need to redirect anything.

undo permanent rewrite rule Nginx

Ok I'm extremely noob to nginx and did something very stupid. I wrote the following code in my sites available file. Deleting it doesn't seem to undo it.
location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {
rewrite ^/(.*)/$ /?page=$1 last;
rewrite ^(.*[^/])$ $1/ permanent;
}
I wrote this before I fully understood what it meant and since have removed it from my configuration file. Despite removing this it looks like it is still effecting one page of my website. I have tried different browsers other than the one that I loaded this page on when the rule was applied and it is still not serving the images correctly.
How can I undo this?
The site is not yet public so I'm not worried about other people's browsers catches still redirecting after this issue is resolved.
Is there a place in my server that is continuing to redirect despite the rule no longer in my sites-available and sites-enabled folder? It is a linux/ubuntu server and so far this is the first site that this server is running.
Thank you for any help or ideas on how to solve this!
According to the rfc2616 section 10.3.2 about http status 301
The requested resource has been assigned a new permanent URI and any
future references to this resource SHOULD use one of the returned
URIs. Clients with link editing capabilities ought to automatically
re-link references to the Request-URI to one or more of the new
references returned by the server, where possible. This response is
cacheable unless indicated otherwise.
A lot of browsers use that to cache the response locally, so that it doesn't waste another request when calling the same URL, unlike 302 which redirects but doesn't cache.
To solve this you just need to clear the local cache, and not even the whole cache, if you did this today you could just clear today's cache and every thing will be back to normal.
If you have add this location block to your/one of your site conf in nginx/sites-available and thereafter symlinked the file to nginx/sites-enabled, it can only be in the nginx/sites-available/site.
However if you copied /nginx/sites-available/site to nginx/sites-enabled/site you also have to delete the file in sites-enabled...
To be sure, did you reload nginx after deleting configuration ?

Allow file access from code, but block from browser?

I have my .htaccess file, and I have a folder with config files in there, and they contain sensitive content, e.g. database details etc. What I would like to know is, how can I block access from a browser, but allow them to be accessed via my scripts?
I know that this can be achieved inside the PHP files themselves, but I'd rather use the .htaccess approach where possible.
Is this actually able to be done? I've attempted it before, but in the process of denying access to the file from the browser, it also denied access from the coding.
I have looked into this before, and some of the answers I came across suggested changing the extension to something like .inc, and then denying access to that. However, a couple of issues I have with that is that a) It instantly alerts anyone that can see that filename, for whatever reason, that it is a config file. Also, b) If my denial code breaks, browsers will not parse it as a PHP file, but rather an inc file, meaning it will print the code in the browser.
Basically, can this be done within a .htaccess file, or do I need to put something in the header of every config file?
Put these files outside of your web server's document root.
You can still access them via your server-side scripts, but this ensures no direct access to them from the outside world.
The conventional advice is to place such files "outside of your web server's document root". This is all well and good, but many shared hosting offerings only give write access to your public_html directory.
I use a simple convention: any private content (that is not URI addressable) is prefixed by an underscore or in a directory that's name is prefixed with an underscore (eg. _private or _include). I then include this rewrite rule in my DOCROOT .htaccess file:
# if a forbidden directory or file name (starting with a . or /)
# then raise 404 Fatal return
RewriteRule (^|/)[_.] - [F]
Remember that you'll need to prefix with a RewriteEngine On and/or include this at the top of any .htaccess file with the engine enabled.
Note that the "." prefix picks up files such as .htaccess.
Please use a framework, these kind of issues just doesn't need to exist. If you insist though, write a .htaccess to redirect every request to a single index.php in the root directory, which then have more logic to determine whether or not the request is for a valid file and include them, otherwise generate 404 or 403. If you need performance for static files, then use RewriteCond to exclude specific directories or file type from the index.php check.

Why does IIS 7.5 adds a trailing slash on folders? Can we disable courtesy redirect for a URL Rewrite rule that removes trailing slash?

IIS does URL cleanup on directories by adding a trailing slash. See this old docs from IIS 6:
IIS generates courtesy redirect when folder without trailing slash is requested
Why? Is the intent still relevant?
Any security implications?
How can I disable it to make this work with a URL Rewrite rule "RemoveTrailingSlashRule"
When you add a rule under IIS 7.5 with URL Rewrite 2, the rule will not be applied to directories (using IsDirectory) and folders (using IsFolder).
See this warning on Add a rule to append or remove the trailing slash symbol:
This will create the RemoveTrailingSlashRule1:
I have an answer for the specific case of a child IIS Application here: https://stackoverflow.com/a/25817317/292060. The child app seems to be the usual culprit, but isn't explicitly described in this question.
To try to answer the questions, here are my opinions from dealing with IIS and Microsoft for years. I don't have hard sources to cite; some of this is just gut feelings.
Why? Is the intent still relevant?
I think it stemmed from the original "default document" feature, namely index.html. Websites wanted their home page to just be the domain, then this extended to subfolders. With url rewriting, the intent isn't relevant anymore - you can rewrite to your heart's content, and would rather IIS get out of the way. It's common to want friendly urls, and no trailing slash (except for the domain/website root - that is required to have a trailing slash, even if some browsers like Chrome get cute and hide it).
Any security implications?
I think the only security implication was the original directory browsing. If you forgot to do a default document, and directory browsing was left turned on, then people could browse your website files. As far as I know, directory browsing has been long disabled as the default setting.
With any requests, whether trailing slash or not, url rewriting or not, your server and code need to withstand bad requests. This is true for all situations, not just specific to the slashes. http://xkcd.com/327/
How can I disable it to make this work with a URL Rewrite rule "RemoveTrailingSlashRule"
I have an answer if the issue is the child application, here: https://stackoverflow.com/a/25817317/292060
The summary is, in IIS:
Disable the Default Document feature for the child application.
Using Url Rewrite, create a rule to rewrite (not redirect) an empty request to default.aspx
If this question is for a more general issue, including regular subfolders even if not a child app, consider removing the "Is Not a Directory" from the rule, and let this redirect even when it sees a directory. That may work, or may create an infinite redirect loop, I'm not sure.

Resources