Blocking directory access with link - .htaccess

I am building a website that has a lot of nested elements so I disabled the access to the directory listings with Options -Indexes in .htaccess but it then throws me the forbidden message (which is good because it works) but I'd like to disable the directory listing by making a redirect to "#".
I just want the user to stay in the same page he was looking if he tries to sneak into my directories...is that possible somehow?

Try:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ %{HTTP_REFERER}# [R,L,NE]
after you re-enable indexes.

Related

htaccess rewrite stopped working properly

I have the following code block in my .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(.*)2021layout(.*)$
[other directories to omit, like assets and admin]
RewriteRule ^(.*) RESThandler.php
Basically I want certain directories to be processed normally, like 2021layout, while others use the REST handler. In the 2021layout directory, the member area is in the directory 2021layout/myaccount, and all css/js files are in 2021layout/assets/[whatever directory]. Both the assets and myaccount directories have permissions 0755.
On Friday, everything was working fine. Today, having changed nothing, pages in the 2021layout directory are working, and css and js files loaded by those pages are fine, but pages in the 2021layout/myaccount directory are trying to use the REST handler and getting redirected to my 404 page.
I have tried renaming both the 2021layout and myaccount directories, which didn't work. I have tried adding !^(.*)2021layout/myaccount(.*)$ as a RewriteCond, and that didn't work.
Why would this one specific directory suddenly stop obeying my htaccess instructions? Can I fix this?
Again, to reiterate: I didn't change anything to make this happen. It worked one day, and the next day it didn't, seemingly on its own.
EDIT: I have gotten the directory to work again by renaming the newly-created file settings.php to mysettings.php. So apparently the mere existence of settings.php within the directory was preventing it from loading correctly. Does anyone have any insight into this?
You may try this rule with THE_REQUEST:
RewriteCond %{THE_REQUEST} !\s/2021layout/ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ RESThandler.php [L]
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. Example value of this variable is GET /index.php?id=123 HTTP/1.1
Make sure to clear your browser cache before testing this change.
So apparently the mere existence of settings.php within the directory was preventing it from loading correctly. Does anyone have any insight into this
I am guessing that you have option MultiViews turned on in your Apache config. To turn it off use this directive at top of your .htaccess:
Option -MultiViews
Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.html.

Trying to put website into Maintenance Mode (302) - 'Too many redirects' htaccess issue

I'm trying to put my webpage into Maintenance Mode by using htaccess to redirect any page that begins with (domain name) to a maintenance.php file within a folder inside the root.
I got this to work on localhost with no issues, but it just won't work when I put it on my web host server. It keeps saying there are too many redirects (there's an infinite loop going on).
# MAINTENANCE-PAGE REDIRECT
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^100\.184\.54\.96
RewriteCond %{REQUEST_URI} !/maintenance/maintenance.php$ [NC]
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif) [NC]
RewriteRule .* /maintenance/maintenance.php [R=302,L]
</IfModule>
I tried plenty of the answers given to other questions such as
.htaccess error - ERR_TOO_MANY_REDIRECTS
htaccess maintenance page redirect results in "too many redirects" error
...among others. The same error keeps coming. I have another domain (domain-1) redirecting to the current webpage (domain-2), tried turning that off to see if it works, nope.
After following a ton of suggestions and styles from around the net, I finally came to a solution that worked for this issue.
To redirect all pages and sub-directories for your domain name to a maintenance page, create two files:
maintenance.html (maintenance page)
maintenance.enable (empty file)
Use the following code in your .htaccess file:
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^105\.228\.123\.16
RewriteCond %{DOCUMENT_ROOT}/maintenance.html -f
RewriteCond %{DOCUMENT_ROOT}/maintenance.enable -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /maintenance.html [R=503,L]
ErrorDocument 503 /maintenance.html
Header Set Cache-Control "max-age=0, no-store"
Be sure to place the 2 files in the same directory as your index page.
That's the solution that worked in my case. I'm yet to try it out with external resources (css/js files and images) but I think it shouldn't take more than some tweaking the above code. Hope it helps someone else too.
EDIT
For external resources and styling just add this line:
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif|css|js|ico)
Be sure to add all of the relevant directories (containing the stylesheets and scripts) in the same directory as the maintenance.html page.
I could be wrong but it seems like a bad idea to use this in conjunction with Header Set Cache-Control "max-age=0, no-store" if you're going to keep the maintenance page up for a while. I leave that for the experts though :-)
My maintenance page is a fancy countdown page.
This is actually part of the problem. Your "fancy" page contains links to numerous CSS and JS files (and the favicon.ico file) - 17 files in total - your .htaccess redirect will redirect these requests as well (all to your maintenance.php page - which will trigger further redirects etc.). You'll need to make additional exceptions for these URL/file extensions. For example:
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^100\.184\.54\.96
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif|css|js|ico)$
RewriteRule !maintenance\.php$ /maintenance/maintenance.php [R=302,L]
The <IfModule mod_rewrite.c> wrapper is not required (you know your server).
The NC flag is not required unless you really do have mixed case extensions.
I realise this isn't a normal "site down for maintenance" type page, however, maintenance pages should ideally link to as few external resources as possible. To avoid issues like the above, but also you don't want to be in a situation where the maintenance page itself cannot be displayed because the site is down for maintenance!

Restricting file/directory access htaccess

I'm slowly starting to learn how to use HTACCESS and the code below doesn't work for some reason the options part itself works.
Options +FollowSymlinks
RewriteEngine on
Options ALL -Indexes
So I'm already restricting users from accessing directories but is there any way to restrict them from accessing all files in certain folders directly?
Right now people are restricted from folders /php/ /css/ etc but if they type /css/style.css they will access that file
Options -Indexes is not used to restrict access per say. It's to prevent listing files in your directory so that they can't access or see all your files in the folder. So if there is no index file it will give a forbidden error.
You need to explicity block access and use other directives. You can use <file> with order, Rewriterule etc.
An example of blocking file types in a directory would be like this.
For instance I have an images directory and want to block jpeg, jpg, png and gifs
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/images [NC]
RewriteCond %{REQUEST_URI} \.(jpe?g|png|gif)$ [NC]
RewriteRule .* - [F,L]
Side note, blocking CSS is prevent irrelevant anyway because the browser has to load it to view the page properly. There's no point to do so because you can inspect any element to see the styles on all modern browsers.

Make files not accessible via URL

How can I redirect via .htaccess file, that only the index.html can be accessed via URL.
I already got this:
RewriteEngine on
RewriteBase /
Options +FollowSymlinks
RewriteRule ^/?login/?$ /php/login.php [NC,R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.html [L,QSA]
It works fine if somebody types in for example "www.mypage.com/skd/lasnd"
but if somebody types in a file which exists on the webserver, e.g. "www.mypage.com/php/login.php", he will be redirected to that page. How to forbid that?
To be more exact: my JavaScript & PHP scripts should be still allowed to access to every file on my webserver.
These lines:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
are conditions "if REQUEST_FILENAME is NOT a file, if REQUEST_FILENAME is not a directory" and if both are met then RewriteRule is taking place. This is usually to allow "friendly urls" to work and at the same time to not rewrite any images, css etc. You can block access to files with many ways, but you have to take care to not block too much (like said images etc). The simplest approach would be to put your files in subdirectory and add another .htaccess file in that directory with line
Deny From All
This will make httpd reny any request to whatever is in that directory and subdirectories (unless another .htaccess overwrite these rules) while your scripts will be able to access them without a problem.
I strongly recommend do read mod_rewrite docs
EDIT
There's no "my javascript" and "their javascript". There's request and that's all you can tell for sure. You cannot tell which access yours and which is not. "i only want to deny request via typing in the browser adress line" - you can't tell that either. You theoretically could check REFERER, and if there's none set then assume it's direct hit, but REFERER comes from browser so it can be faked as well. And I personally block all REFERERS by default, so all my requests are w/o any REFERER even these not direct. You could try cookies, but again - these can be be grabbed by script and sent back too. The only real option is to Deny from all to these files and "tunel" them thru some sort of script (i.e. PHP) that would do i.e. file() on target file only if user authenticated himself previously using login and password. Any other attempts are broken from the start.
try the following
RewriteRule /.* http://www.new-domain.com/index.html

.htaccess, proper rewriting of directory and file with same name

As of now my website has a few static pages, one of which is /portfolio. Among other things, my htaccess hides the .html extension. I'd like to add a portfolio directory, but I do not want to move my existing portfolio page into the portfolio directory as the default index file. My /portfolio page is one of my Google sitelinks and I am afraid if it is moved or if the url changes in someway, Google will consider it to be a brand new page.
My problem is once I add the /portfolio/ directory, whenever I try to visit the original /portfolio page, a trailing slash is automatically added and it links to the directory itself.
I've tried countless options, one being a rewrite of /portfolio/ to /portfolio, however this creates an infinite loop. I also tried "DirectorySlash Off" but that only removed the trailing slash while being inside the directory, it didn't revert access to the original /portfolio page.
Ultimately, I would like to keep my /portfolio page as-is, linking to pages inside the directory like so /portfolio/example and if either /portfolio or /portfolio/ is accessed it will result in showing the same page which is outside of the directory without Google thinking it is duplicate content.
A similar question exists here:
.htaccess rewriting url to page or directory though this still resulted in an infinite loop for me for some reason, I'm guess it has something to do with the hidden extensions.
Here's my htaccess-
RewriteEngine On
# HTML to PHP
RemoveHandler .html .htm
AddType application/x-httpd-php .htm .html
# Hide extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
# Force WWW
RewriteCond %{HTTP_HOST} ^mydomain\.net
RewriteRule ^(.*)$ http://www.mydomain.net/$1 [R=301,L]
# Blog Subdomain
RewriteCond %{HTTP_HOST} ^blog.mydomain.net$
RewriteRule ^(.*)$ http://www.mydomain.net/blog/$1 [R=301,L]
I know it's not a great idea having a directory with the same name as a static page, but I really would rather not alter the existing page and lose the Google sitelink, so a clean and proper way to handle this would be a help.
There are two things going "wrong" here, and two ways to fix it.
The first is that apache "figures out" that there is a directory by the name of "portfolio" before the rewrite conditions are applied. That means that the rewrite conditions are receiving "portfolio/" instead of "portfolio".
Second, the "!-d" rule is specifically avoiding the rewrite that you want to make if there is in fact a directory by that name
Solution 1: Manually re-route requests for the portfolio directory to remove the slash.
# Manually re-route portfolio/ requests to portfolio
RewriteCond %{REQUEST_FILENAME} portfolio/$
RewriteRule ^(.*)/$ $1
# Hide extension
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
Note the removal of the "!-d" condition.
The downside to this is that you are having to hard-code the "portfolio" edge case directly into the rewrite rules, and will still result in the browser being first redirected to portfolio/
Solution 2: Set DirectorySlash Off and remove directory exists test
# Disable Automatic Directory detection
DirectorySlash Off
# Hide extension
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
Setting DirectorySlash Off would fix this issue the best, but may break other parts of your site where you actually want the auto DirectorySlash. Best of Luck, and I hope this helps.
Note when testing solution 2, your browser may remember the redirect of "portfolio" to "portfolio/" and perform the redirect before it even sends the request to the server. Be sure to test in a cache-clear, clean environment for best results.

Resources