How to apply RewriteRule properly on forbidden files? - .htaccess

The goal
If the request is http://⋯/.htaccess,
do not display the content of that file,
show an ErrorDocument 403 instead,
rewriting only http:// to https://.
The problem
The URL is rewritten to https://⋯/403.shtml,
instead of the desired https://⋯/.htaccess.
The details
The ErrorDocument 403 and the protection of the
.htaccess are set up by the web hosting provider.
The HTTPS rewrite is set up in the .htaccess file:
RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteRule .* https://%{HTTP_HOST}/$0 [L,QSA,R=301]

<If "%{HTTPS} != 'on'">
Require all granted
RewriteEngine on
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,QSA,R=301]
</If>

Set the following in your .htaccess file to reset the default 403 Apache ErrorDocument:
ErrorDocument 403 default
The ErrorDocument 403 and the protection of the .htaccess are set up by the web hosting provider.
It looks like the host has configured the ErrorDocument directive with an absolute URL to the 403.shtml document, which will naturally trigger a 302 redirect instead of an internal subrequest.

Related

htaccess file make redirection to another file

I have htaccess file below
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
Redirect /index.html /login.html
ErrorDocument 404 /404.html
ErrorDocument 403 /403.html
Options -Indexes
Redirect /index.html /login.html
When user enters index page it should redirect to login.html page.
But it doesn't work.
Redirect /index.html /login.html
im requesting /index
If you are requesting /index then I'm not sure why you are checking for /index.html in your rule. However, you should be using mod_rewrite to construct this redirect since you are already using mod_rewrite for your internal rewrites.
So, have it like this instead:
Options -Indexes
ErrorDocument 404 /404.html
ErrorDocument 403 /403.html
RewriteEngine On
RewriteBase /
# Redirect "/index" to "/login"
RewriteRule ^index$ /login [R=302,L]
# Append ".html" if target file exists
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule (.*) $1.html [L]
I've also "fixed" your .html rewrite since this could result in a 500 error for certain requests and there's no need to check that the request does not map to a directory before checking that the request does map to a file.
See the following question on ServerFault that expands on this potential issue regarding .html removal. https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error

Forwarding Path With .htaccess

I use cPanel hosting on https://files.example.com and I'd like https://files.example.com/anything-here to redirect to my main website and forward the path, so you'd end up on https://www.example.com/anything-here. Is this possible?
Note that I also have a forced SSL redirect inside my .htaccess file.
https://www.example.com is a Google Site.
My .htaccess file:
ErrorDocument 400 /index.html
ErrorDocument 401 /index.html
ErrorDocument 403 /index.html
ErrorDocument 404 /index.html
ErrorDocument 500 /index.html
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"
https://www.example.com is a Google Site.
If the two sites are on different servers and you simply need to redirect everything from one host to the other and maintain the same URL-path then you don't appear to need anything in your .htaccess file at files.example.com except for the following mod_alias Redirect directive:
# Redirect everything to https://www.example.com/ and maintain URL-path
Redirect 302 / https://www.example.com/
The Redirect directive is prefix matching and everything after the match is copied onto the end of the target URL. So, a request for /foo is redirected to https://www.example.com/foo.
If, however, you have other hostnames pointing to your cPanel account then you'll need to use a mod_rewrite rule and check the requested hostname.
For example, at the end of your existing .htaccess file:
# Redirect every request for "files.example.com"
# to https://www.example.com/ and maintain URL-path
RewriteCond %{HTTP_HOST} ^files\.example\.com [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=302,L]
Reference:
https://httpd.apache.org/docs/2.4/mod/mod_alias.html#redirect
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
UPDATE#1:
But I just realised that it's also forwarding the path for files that do exist on my hosting. I onlt want it to forward invalid paths through to www.example.com.
In that case, you'll need to do it like this instead:
RewriteCond %{HTTP_HOST} ^files\.example\.com [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=302,L]
The 2nd and 3rd conditions check that the request does not map to an existing file (or directory) before issuing the redirect.
Remove the first condition that checks the HTTP_HOST if it's not required.
UPDATE#2:
Is there a way to have it exclude "/URL" from this? If "URL" is specified in the path (example.com/URL/whatever) then I do not want this .htaccess rule to take place. I just want it to use my ErrorDocuments for this path.
If it's just the one pattern you want to exclude, ie. all URLs that start /URL then you can modify just the RewritRule directive. For example:
:
RewriteRule !^URL https://www.example.com%{REQUEST_URI} [R=302,L]
Any URLs that do not start /URL will be excluded. Note that this also includes /URLwhatever, not just /URL/whatever.

htaccess not redirecting all not found page or URL on site to 404 pages

Try to set 404 page not found error page by htaccess.
Issue is if we are searching for
https://www.rsseosolution.com/suraj.html ... Its redirect perfect to 404.php.
But if we are searching for
https://www.rsseosolution.com/suraj.php ... Its not redirecting to 404.php and giving showing simple text message "File not found.".
In short problem is if extension is not php then its redirecting fine but if .php then its showing File not found.
ErrorDocument 404 https://www.rsseosolution.com/404.php
Options +FollowSymLinks
RewriteEngine on
# ensure www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteRule seo-package-(.*)-n-(.*)\.php$ seo-package-detail.php?id=$1&name=$2 [NC,L]
RewriteRule case-studies/(.*)-(.*)\.php$ case-studies.php?project=$1&id=$2 [NC,L]
RewriteRule tutorial/(.*)-(.*)\.php$ tutorial.php?topic=$1&id=$2 [NC,L]
RewriteRule blog-page-(.*)\.php$ blog.php?page=$1 [NC,L]
RewriteRule seo-tutorial-(.*)\.php$ seo-tutorial.php?page=$1 [NC,L]
RewriteRule frequently-ask-question-faq-(.*)\.php$ frequently-ask-question-faq.php?page=$1 [NC,L]
What i am looking for is ....... redirect all not found or wrong URL to 404.php.
What i am missing here.
I think because we are rewriting some URLs with .php extension from htaccess and thats why for PHP its saying file not found but for other its redirecting perfectly to 404.php.
Is there any ways to set 404.php for all not found pages and URL without change any extension (.php) of previous written file by htaccess.
The problem is not to do with your current directives in .htaccess.
The problem is mostly likely due to your server config and the way PHP is implemented on your server. If requests for .php files are proxied to a backend server for processing as is often the case with FastCGI type configs then this 404 Not Found message is likely coming from the backend server and not your Apache server.
Ordinarily, you would solve this with the ProxyErrorOverride directive in the reverse proxy config:
ProxyErrorOverride On
If you don't have access to the main server config then you may be able to trigger the 404 early using mod_rewrite in .htaccess, before the request is sent to the proxy server.
For example, before your existing mod_rewrite directives:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.php$ - [R=404]
However, this is strictly a "workaround", if you have access to the server config then using ProxyErrorOverride (as mentioned above) is preferable.
Aside:
ErrorDocument 404 https://www.rsseosolution.com/404.php
By specifying an absolute URL in the ErrorDocument directive this triggers an external (302) redirect for the error document (an additional request), which is generally undesirable (and you need to manually set the 404 response code). It is far better to issue the error document as an internal subrequest instead:
ErrorDocument 404 /404.php

How to redirect from folder having permission `Deny from all`, error `You don't have permission to access / on this server`

I have .htaccess in /domainName folder with rule Deny from all and some other rules.
After this if i type :
http://www.domainName.com - i am redirected correctly
http://www.domainName.com/uri - i am redirected correctly
domainName.com - i am getting the error You don't have permission to access / on this server. Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.
Structure:
/domainName/
/domainName/.htaccess
/domainName/public
/domainName/public/.htaccess
/domainName/.htaccess
RewriteEngine On
RewriteBase /
Options -MultiViews
Redirect https://domainName.com https://www.domainName.com/public/index\.php
Redirect https://www.domainName.com https://www.domainName.com/public/index\.php
Redirect http://domainName.com https://www.domainName.com/public/index\.php
Redirect http://www.domainName.com https://www.domainName.com/public/index\.php
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.%{HTTP_HOST}%{REQUEST_URI}
#1# the error You don't have permission to access / on this server. Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.
# Deny from all
#2#does not give errors, but i am not able to access https://www.domainName.com/public/index.php, dditionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.
#<FilesMatch ".">
# Deny from all
#</FilesMatch>
#3# gives errors, about wrong configuration
# <DirectoryMatch ".">
# Deny from all
# </DirectoryMatch>
Seems, that one has to redirect in case of deny:
Deny from all
ErrorDocument 403 https://www.somedomain.com/public/index.php/
If redirect in case of deny, there will not be the error for url somedomain.com, or www. somedomain.com
Structure:
/domainName/
/domainName/.htaccess
/domainName/public
/domainName/public/.htaccess
When in somedomain.com/public/ there shall be another .htaccess, whith rule Allow from all.
Full .htacess
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
Options -MultiViews
DirectoryIndex /public/index.php
#redirect to https
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
#[L,R=301]
# Now, rewrite any request to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Deny from all
ErrorDocument 403 https://www.somedomain.com/public/index.php/
In somedomain.com/public/ there shall be another .htaccess, whith rule Allow from all.
the error You don't have permission to access / on this server. Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.

different 404 for subdirectory when paths are handled by index.php

I'd like /blog/anything-that-doesn't-exist to redirect to /blog, while any other 404s are handled by Drupal.
My htaccess currently has:
ErrorDocument 404 /index.php
So everything is handled by Drupal. Is it possible to have a subdirectory specific 404 rule, but set that from the root directory htaccess? The /blog/ subdirectory is generated by Drupal, so I can't put an overriding htaccess in there.
You can use the following code in your Root/.htaccess file :
RewriteEngine On
#If /blog/foo is not a directory
RewriteCond %{DOCUMENT_ROOT}/blog/$1 !-d
#And /blog/foo is not a file
RewriteCond %{DOCUMENT_ROOT}/blog/$1 !-f
#Then redirect /blog/foo to /blog
RewriteRule ^blog/(.+)$ /blog/ [NC,L,R]
It is worth noting that, the Execution time of RewriteRule and ErrorDocument directive is diffrent. RewriteRule directive executes before the ErrorDocument directive, so any request for /blog/bad_url will be handled by the rule above, and all other 404 requests will be handled by the ErrorDocument.

Resources