3

I have a domain on which I am trying to set custom redirects for the error pages.
My .htaccess file looks like so:

RewriteEngine On
AddDefaultCharset UTF-8
DefaultLanguage en-US
# disable TRACK and TRACE http methods. 'RewriteEngine On' is required!
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|OPTIONS|HEAD|PUT|DELETE)
RewriteRule .* - [F]
Options All -Indexes
ServerSignature Off
<ifModule mod_headers.c>
        Header unset X-Powered-By
</ifModule>
<Files .htaccess>
order allow,deny
deny from all
</Files>
<IfModule php5_module>
        php_value session.cookie_httponly true
        #php_value session.cookie_secure true
</IfModule>
RewriteCond %{QUERY_STRING} _escaped_fragment_=(.*)
#to block all links to '.gif', '.jpg','.js' and '.css'  files which are not from the domain name 'http://www.example.com/'
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example.com/.*$ [NC]
RewriteRule \.(gif|jpg|css|js)$ - [F]
#to deny requests containing invalid characters
RewriteBase /
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ [a-zA-Z0-9\.\+_/\-\?\=\&]+\ HTTP/ [NC]
RewriteRule .* - [F,NS,L]

# Secure directories by disabling execution of scripts
AddHandler .php .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI


#Error page handeller
ErrorDocument 400 /htaccessSample/errordocs/error-code.php
ErrorDocument 401 /htaccessSample/errordocs/error-code.php
ErrorDocument 403 /htaccessSample/errordocs/error-code.php
ErrorDocument 404 /htaccessSample/errordocs/error-code.php

When I type something on the URL like so:

  • example.com/aboutUs: Everything works normally.
  • example.com/xxygsds: The URL is redirected to the custom 404 error page.
  • example.com/<>: This redirects to the 403 forbidden page. However, the redirect is to the apache/error/HTTP_FORBIDDEN.html.var page and not to the custom page as mentioned above.

My questions:
1. Why is this redirect happening?
2. How can I have it redirect to the custom 403 error page in all conditions?

hjpotter92
  • 660
  • 1
  • 10
  • 20
Sriram
  • 201
  • 4
  • 8

2 Answers2

0

Im no sure why it does that. Got the same issue with my 403 page. If you want to redirect a specific 403 page use this:

<Files some_thing> 
order Deny,Allow 
Deny from all 
</Files>
0

Try moving your error document locations to the TOP of your .htaccess file. I looked at your example for a while trying to figure out what was happening, then finally realized that the thing is being told to exit before it's told where to exit to in this case.

Apache is reading the directives in order, and exits on the L case. The L is implicit in F:

When using [F], an [L] is implied - that is, the response is returned immediately, and no further rules are evaluated. https://httpd.apache.org/docs/2.4/rewrite/flags.html

So I am guessing that apache simply never gets to that set of instructions when it hits the true, matching, case of your <> example. Which then sends the page to the default apache 403 error page, since it exited before it reached those declarations. Your 404 worked because it never triggered any of the rules that contain a L condition, ie, last thing to execute, and so reached the bottom of the htaccess rules.

I've never hit this situation because I always put the default error pages on TOP of the directive, by habit, along with other core things like php ini adjustments etc.

The rewrites go on the bottom.

The goal being, everything you wanted to tell apache has been told to apache by the time it hits the L case for a rewrite, or the end of the htacess/config rules. If it wasn't htaccess, apache would have known all the rules when it started serving your site, but with htacess, I believe it just reads them and does what the file tells it.

I believe this is right, but I'm not 100% sure, since I've always put the stuff that should be on top on top, and thus never triggered your case. The key is to realize that L, Last, really does mean Last, and then to know as well that F implies L.

In general, it pays to be organized when dealing with apache configurations:

# top generics etc
#Error page handler
ErrorDocument 400 /htaccessSample/errordocs/error-code.php
ErrorDocument 401 /htaccessSample/errordocs/error-code.php
ErrorDocument 403 /htaccessSample/errordocs/error-code.php
ErrorDocument 404 /htaccessSample/errordocs/error-code.php

AddDefaultCharset UTF-8
DefaultLanguage en-US
# Disable Directory Browsing, not related to rewrite
Options All -Indexes

# Secure directories by disabling execution of scripts
AddHandler .php .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI

ServerSignature Off
<ifModule mod_headers.c>
        Header unset X-Powered-By
</ifModule>

<IfModule php5_module>
        php_value session.cookie_httponly true
        #php_value session.cookie_secure true
</IfModule>

<Files .htaccess>
order allow,deny
deny from all
</Files>

## NOW do the set of rewrite rules, everything that apache needs to 
## know has been told to it by this point
RewriteEngine On
# disable TRACK and TRACE http methods. 'RewriteEngine On' is required!
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|OPTIONS|HEAD|PUT|DELETE)
RewriteRule .* - [F]

RewriteCond %{QUERY_STRING} _escaped_fragment_=(.*)
#to block all links to '.gif', '.jpg','.js' and '.css'  files which are not from the domain name 'http://www.example.com/'
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example.com/.*$ [NC]
RewriteRule \.(gif|jpg|css|js)$ - [F]
#to deny requests containing invalid characters
RewriteBase /
RewriteCond %{THE_REQUEST} !^[A-Z]{3,9}\ [a-zA-Z0-9\.\+_/\-\?\=\&]+\ HTTP/ [NC]
RewriteRule .* - [F,NS,L]

Remember to add always a newline/line break at the end of your .htaccess file. Your version is extremely random and disorganized, which is the actual cause in my opinion of your issues, if you simply get accustomed to ordering your rules clearly and consistently (ie, rewrites are not mixed in with other rules), you'll find it a lot easier to work with apache in general.

Lizardx
  • 210
  • 1
  • 8