当您决定返回403时,始终返回404

时间:2012-05-09 04:27:57

标签: security http .htaccess http-status-code-403

此处已经发布了几个关于在特殊情况下返回404而不是403的问题(例如,.ht *文件或某个目录),但我无法弄清楚如何简单地替换 all < / strong> 403回复(“好的,它存在,但你仍然需要找到一种方式”)与404s(“对不起,从未听说过”)。我希望有一个简单的解决方案,不需要更新正则表达式或.htaccess的其他位来匹配站点更改,只需一个简单的指令:“每当你决定返回403时,返回404代替”无论配置如何变化,都可以访问整个站点。

然后,如果顶级.htaccess包含“Options -Indexes”,并且任何给定目录不包含index.html(或者equiv),则裸目录URL将返回404,但是如果我曾经添加一个index.html该目录,相同的裸目录URL将返回index.html,不需要任何.htaccess文件的更新。

我甚至不关心,如果我曾经密码过一个目录,那么一个错误的密码会返回一个404(因为404 - &gt; 403映射)。在那种情况下,我没有通过返回404隐藏任何东西,但它也没有造成任何伤害。如果有办法取消对特殊情况的一般403-> 404映射(而不是特殊情况下的DO),那可能会更有用。

当然,如果我忽略了什么,请让我直截了当。

编辑:Drat。我试图在这里写一个质量好的问题,但我在第二段中对“选项 - 索引”行为的描述结果证明是错误的。没有该行,如果存在于目录中,则裸目录URL显示“index.html”;否则,它会显示目录的内容。 (如果index.html存在,将/ dir转发到/dir/index.html是Web主机的默认设置,除非我弄错了。)添加“Options -Indexes”行会阻止它在公共场所播放我的衣物(返回403,而不是404,但仍然比暴露dir内容更好),但现在即使index.html存在,裸目录URL也会返回403。

我希望一个裸露的网址“mysite.com/mydir”显示/mydir/index.html如果它存在,“404”如果没有,但显然它不仅仅是用404替换403s。

5 个答案:

答案 0 :(得分:12)

要完成其中一个更好的答案(如@WebChemist和@JennyD所述),解决此问题的一个好方法是从用于处理404 Not Found错误的文档中返回403。我个人会做以下事情:

Web根目录中的

.htaccess相关摘录):

ErrorDocument 400 /http-errors.php
ErrorDocument 403 /http-errors.php
ErrorDocument 404 /http-errors.php
Web根目录中的

http-errors.php简明工作示例):

<?php

$status = $_SERVER['REDIRECT_STATUS'];
// If it's a 403, just bump it up to a 404
if ( $status == 403 ) $status++;

$codes = array(
  400 => array( '400 Bad Request', 'The request cannot be fulfilled due to...' ),
  404 => array( '404 Not Found', 'The resource you requested was not found...' ),
  500 => array( '500 Internal Server Error', 'The request was unsuccessful...' )
);

$title = $codes[$status][0];
$message = $codes[$status][1];

header( $_SERVER['SERVER_PROTOCOL'] . ' ' . $title );
echo "<h1>$title</h1>\n<p>$message</p>";

答案 1 :(得分:3)

你可以轻松做假403 - &gt; 404做

ErrorDocument 403 /404.php

404.php是您格式化的404响应页面,但仍会在响应标头中返回403。如果你想返回404标题,你可以创建一个403页面,其中包含一个返回404代码的标题重定向,但重定向可能仍然可见....

不确定你是否可以使用纯.htaccess进行403-> 404替换

修改

可以尝试使用2种纯粹的.htaccess方法:

1)将任何以斜杠结尾的url重定向到索引页面,如:

RewriteRule ^(.*)/$ /$1/index.php [NC,L]

所以如果你有一个索引页面,它会显示但是如果没有它将在缺失索引页面请求上404。如果你遗漏了[R],网址仍将显示为/ non index.php规范的SEO友好网址:)不能说这不会导致其他地方出现问题..

2)

在重写规则中,您可以使用r = 404返回404代码。

RewriteRule ^(.*)/$ - [R=404, NC,L]

然而 RewriteCond %{REQUEST_FILENAME} !-f 要么 RewriteCond %{REQUEST_FILENAME} -d

没有帮助,这意味着即使存在索引页面,所有尾部斜杠也将为404。您可以通过在其他RewriteCond规则中指定要保护(或忽略)的文件夹来解决此问题,但这并不完全是“自动”,因为您必须添加RewriteCond规则,因为更多文件夹被添加到保护|忽略

答案 2 :(得分:3)

这是我的.htaccess文件中的一个片段,它位于我已阻止的目录中,但允许从LAN计算机进行访问。每次返回404错误!!

# Turn rewrite engine on
RewriteEngine on
RewriteOptions Inherit

# Make it for a specific directory
# RewriteBase /phpMyAdmin 

# Block everyone except me
RewriteCond %{REMOTE_HOST} !^192.168.2
RewriteRule .? - [R=404,L]

答案 3 :(得分:2)

据我所知,没有这么简单的指示。它仍然有可能,但它比你想要的要复杂一点。

您可以使用ErrorDocument指令设置对脚本的403响应,然后让该脚本响应404响应而不是403响应。 apache.org提供了一些可能有用的提示

答案 4 :(得分:-1)

即使可能没有一种方法可以获得403错误来报告404错误,但仍有希望。

我怀疑你真正想要的是确保/~root(以及任何其他现有的非HTTP用户)不会回馈403而是404.

Apache中的UserDir指令按设计返回403。我认为目前无法改变。但是 - 用户目录&#39;指令可以在同一个Apache文件中多次使用:

UserDir public_html UserDir禁用root someuser1 someuser1

该配置将允许使用UserDir,但也会向所有试图嗅探系统的人报告珍爱的404响应标题。

我从以下链接中找到了这个提示:

http://www.if-not-true-then-false.com/2010/enable-apache-userdir-with-selinux-on-fedora-centos-red-hat-rhel/

我在RHEL 6.3下的Apache 2.2.15中自己进行了测试,它可以工作 - 即使在使用像curl这样的测试时也是如此。我也在寻找解决方案。终于找到了我可以使用的东西!