2

我正在开发一个网站,由于用户输入或其他原因,我需要显示一些错误消息。为此,我有一个名为error.php的页面,并使用 $_GET 获取错误号。所有错误消息都存储在一个数组中。

例子:

header( 'Location: error.php?n=11' ); 

但我不希望用户在 URL 中输入错误代码并查看所有其他错误消息。为了防止这种情况,我认为我可以将引用页面列入白名单,并且仅在我的白名单中找到引用者时才显示错误消息。

它应该与此类似(尚未测试;))

$accept = false;
$allowedReferer = array (0=>'page1.php', 'page2.php');
if (in_array($_SERVER['HTTP_REFERER'], $allowedReferer )) {$accept = true;}
if ($accept) { $n=$_GET['n'];echo "Error: " . $errorList[$n];}

这种方法是否足以避免间谍用户

我用 PHP5 做这个

谢谢

4

7 回答 7

8

不,它不是远程安全的:HTTP Referer标头很容易被欺骗,也不是必需的标头。我建议您阅读这篇文章以获取利用代码(用 PHP 编写)的示例,或者下载这个用于 Firefox 的附加组件,以便在您自己的浏览器中舒适地进行操作。

此外,您的$allowedReferer数组应该包含完整的 URL,而不仅仅是脚本名称,否则代码也将可以从远程引用中被利用,例如来自

http://www.example.org/page1.php

总而言之:您不能在不要求身份验证的情况下限制对任何公共网络资源的访问。

于 2009-02-19T10:58:23.817 回答
5

而不是重定向,您可以简单地“就地”显示错误 - 例如像调整您当前的代码一样简单的东西

if ($error_condition)
{
    $_GET['n']=11;
    include "/path/to/error.php";
    exit;
}

在实践中它可能会更复杂一点,但想法是一样的——用户会看到一条错误消息而无需重定向。确保输出某种错误标头,例如 header("HTTP/1.0 401 Bad Request") 以告诉浏览器它并没有真正看到请求的页面。

如果您确实想重定向,那么您可以通过包含错误编号的哈希值和只有您的代码知道的盐来创建“防篡改”URL,例如

$n=11;
$secret="foobar";
$hash=md5($n.$secret);
$url="http://{$_SERVER['HTTP_HOST']}/error.php?n={$n}&hash={$hash}";

现在您的 error.php 可以检查是否正确创建了提供的哈希。如果是,那么它很可能是由您的代码而不是用户创建的。

于 2009-02-19T11:17:36.423 回答
4

您不应该使用外部重定向来访问错误页面。我的 PHP 结构是这样的:

我有一个包含在每个页面中的通用文件,具有通用功能:处理登录/注销、设置常量等。有一个 error() 函数,您可以将错误信息传递给它将显示错误页面并退出。另一种方法是使用 index.php?include=pagename.php 习惯用法来实现通用功能,但我发现这更加不稳定且容易出错。

如果您从外部重定向客户端(有时显然需要这样做),则永远不要依赖通过该机制传递的信息。像所有用户输入一样,它本质上是不可信的,应该非常谨慎地进行清理和处理。也不要使用 cookie(同样的问题)。如果您需要在请求之间保留信息,请使用会话。

于 2009-02-19T11:06:39.960 回答
1

HTTP_REFERER那些有足够激励措施的人可以轻而易举地欺骗(telnet是那里选择的工具),并且不应该被信任。

无论如何,错误消息都不应该透露任何关键信息,因此我建议您将错误消息设计为可以显示给任何人的方式。

那,或者使用随机哈希来识别错误(而不是11,使用98d1ud109j2等),这些错误将存储在某个关联数组的中心位置:

$errors[A_VERY_FATAL_ERROR] => "308dj10ijd"
于 2009-02-19T11:00:47.697 回答
1

为什么不只包含错误消息脚本?为了摆脱以前的输出数据,使用输出控件缓冲它并在错误时清除它:

if ($error) {
    ob_clear();
    $errorCode = 11;
    include 'error.php';
    exit;
}
于 2009-02-19T11:38:32.863 回答
0

为什么不包含错误页面,而不是重定向到错误页面。您可以使用 .htaccess 限制对包含包含错误内容的 php 文件的目录的访问:

RedirectMatch 404 ^error-pages/*$

在错误页面中,您可以拥有显示错误的可包含页面。

使用这种方法,您可以确保没有人可以直接访问错误页面目录中的页面,但您仍然可以将它们包含在可公开访问的脚本中。

于 2009-02-19T11:09:27.973 回答
0

如果您在发送标头之前处理错误,您可以轻松地创建一个输出带有内容的基本 html 页面的函数,并在它之后立即退出。这样就不需要任何其他页面(我猜除了功能页面)。

就像检查是否有问题一样简单,如果有问题,只需调用该函数。

我使用这样的函数,它甚至在被调用时会写入数据,所以我有自己的错误日志......

于 2009-02-19T11:30:55.253 回答