Is there a way to force apache to return 404 instead of 403?
Asked Answered
L

4

30

Is there a way how I can configure the Apache web server to return a 404 (not found) error code instead of 403 (forbidden) for some specific directories which I want to disallow to be accessed?

I found some solutions suggesting the use of mod_rewrite, like e.g.

RewriteEngine On
RewriteRule ^.*$ /404 [L]

As the purpose of sending 404 instead of 403 is to obfuscate the directory structure, this solution is too revealing, because it redirects to some different location which makes it obvious that the directory originally accessed does in fact exist.

Lankester answered 28/9, 2009 at 10:13 Comment(2)
Does this question solve your problem?Farlie
I didn't consider this question when I first saw it (too confusing), but after a second glance I found the line I've been looking for, thanks.Lankester
L
31

RedirectMatch as in e.g.

RedirectMatch 404 /\.

does the trick, it prohibits access to all files or directories starting with a dot, giving a "404 Not Found" error.

From the Apache manual: "The Redirect[Match] directive maps an old URL into a new one by asking the client to refetch the resource at the new location." By default, Redirect sends a 302 return code, but it can also return other status codes as shown above.

Lankester answered 28/9, 2009 at 15:41 Comment(5)
+1, but to match a single dot anywhere in the url path, do we really need the quotes and the dot-star? I.e., can't we just do RedirectMatch 404 /\. instead of RedirectMatch 404 ".*\/\..*" ?Ceasefire
@Lankester it returns 403 for ".git/.htaccess"and ".git/.php" instead of 404Isolda
@Awaaaaarghhh, that's likely because you have a FilesMatch directive in your apache configuration that takes precedence. A custom ErrorDocument for 403 as suggested in Tomer's answer would cover this case, too, but requires php.Lankester
@Lankester but requires php, no, why php?! - you can use also static html documents like "my404error.html" for your custom ErrorDocument! that's likely because you have a FilesMatch dir, no, i tested it without RedirectMatch. anyway thank you! :) I was able to fix everything, now all requests return 404 error: https://mcmap.net/q/500368/-htaccess-make-a-directory-invisible (I used FilesMatch). I tested a lot & read apache docs, but was not able to use RedirectMatch properly in that specific case.Isolda
Because with html you won't be able to change 403 to 404.Lankester
M
10

You can make something like this:

.htaccess

ErrorDocument 403 /error/404.php

404.php

<?php
$status = $_SERVER['REDIRECT_STATUS'] = 404;
header( $_SERVER['SERVER_PROTOCOL'] . ' ' . $status);
?>

404 Error
Meimeibers answered 7/8, 2013 at 17:4 Comment(5)
Why is this not upvoted enough? I used this solution. It's very straightforward. However, since I have PHP >= 5.4.0, I simply used <?php http_response_code(404); ?> at the top of the 404.php page. This way I can use ErrorDocument *** any code *** /error/404.php and they will all become 404 in the HTTP header.Schwerin
What if I want to send all requests to a unique index.php front controller script and have it decide if 404.php should be executed?Knowledgeable
@ADTC, it's not relevant to the question, which was how to ask Apache to do this, not PHP.Sparkman
@ChrisCogdon How to ask Apache to do this > this is exactly what .htaccess, an Apache-readable file, does. So in the end, this answer is still asking Apache to do this. Apache executes the 404.php file when there is a 403 error. PHP parses the file and sends the output through Apache web server to the browser. Where's the irrelevancy in this?Schwerin
@Knowledgeable you simply need to redirect all the error codes to index.php and write the PHP script in it to do the needful (check and decide if 404, then include 404.php otherwise include some other content).Schwerin
I
6

After having the same problem, I ended up with the following .htaccess file

Options -Indexes
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain.com [NC]
RewriteRule ^(.*)/$ - [R=404,NC]

The 1st and 3rd line ensure that you can't list the folder content, and if you do it you will receive a 404 error. The RewriteCond directive ensures that this rewrite rule only applies to main domain. Since I have several subdomains, without the rewritecond, accessing www.mydomain.com/subdomain was also returning a 404, which was not what I intended.

Intermezzo answered 12/1, 2014 at 12:49 Comment(2)
This works well for me. Just one issue is the way Options -Indexes works: /img/ (which doesn't exist) correctly returned a 404, but /img/ (which does exist and I want access to, but not a directory listing for) returned a 403. So, what I did was remove Options -Indexes and just make sure the regexes (that specify allowed files) never match just a directory name.Riella
*That is not a subdomain, but a sub-site..., could be bypassed by RewriteCond for directory check (... -d ...)...Hell
H
1

In my opinion making this task in .htaccess is quite ugly solution.

It is possible to make it in apache configuration. Take a look:

Add to your apache config:

ErrorDocument 403 /404

Then restart apache:

service apache2 restart

That is all.

Haihaida answered 3/4, 2020 at 8:3 Comment(1)
That line alone oesn't work (no matter whether you put it in htaccess or apache config).Rhee

© 2022 - 2024 — McMap. All rights reserved.