2009-02-19 53 views
2

我正在开发一个网站,并且由于用户输入或其他原因,我需要显示一些错误消息。 为此,我有一个名为error.php的页面,并使用$ _GET获取错误号。所有错误消息都存储在一个数组中。此方法是否足够安全以便向用户显示错误? - PHP

例子:

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

这样

感谢

回答

5

而不是重定向,你可以简单地显示错误“就地” - 例如,东西像

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

的东西适应您的本次代码实际上它可能是一个小更复杂为简单,但这个想法是一样的 - 用户提供一个错误信息,而不会重定向。确保输出某种错误标题,例如头文件(“HTTP/1.0 401错误请求”)告诉浏览器它没有真正看到请求的页面。

如果你确实想要重定向,那么你可以创建一个“防篡改”URL,方法是在你的代码中包含一个只有你的代码才知道的含有错误号的散列。

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

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

+0

+1对于盐渍散列。 – 2009-02-19 11:20:39

8

不,它不是远程安全:在HTTPReferer头是微不足道的欺骗,而不是一个必需头无论是。我建议您阅读this article以获取利用代码(使用PHP编写)的示例,或者下载用于Firefox的this add-on,以便从您自己的浏览器中自行完成。

此外,您$allowedReferer数组应该包含 URL的,不只是脚本的名称,否则代码也将是远程请示,例如可利用从

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

总结:你不能限制存取任何公共网络资源,而无需认证。

1

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

错误消息不应该透露任何关键的东西,所以我建议你设计你的错误消息,以便他们可以显示给任何人。

也就是说,或使用随机哈希来识别错误(而不是11,使用98d1ud109j2等),将被存储在一个中心位置在关联数组中的某处:

$errors[A_VERY_FATAL_ERROR] => "308dj10ijd"
4

你不应该使用外部重定向到达错误页面。我如何构建我的PHP是这样的:

我有一个共同的文件,包含在每个页面,具有常用功能:处理登录/注销,设置常量等。在那里有一个错误()函数,您可以将错误信息传递给那个将显示错误页面并退出的错误信息。另一种方法是使用index.php?include = pagename.php成语来实现通用功能,但我觉得这样更加脆弱和容易出错。

如果您在外部重定向客户端(您显然需要这样做),决不要依赖通过该机制传递的信息。像所有的用户输入一样,它本质上是不可信的,应该进行消毒和处理时要格外小心。不要使用cookies(同样的问题)。如果您需要在请求之间保留信息,请使用会话。

0

而不是重定向到一个错误页面为什么不包括一个错误页面。您可以限制访问包含包含错误内容与.htaccess中的PHP文件的目录:

RedirectMatch 404 ^error-pages/*$ 

和错误页面里,你可以有包括-能够页这显示错误。

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

0

如果您在发送标题前处理错误,您可以轻松创建一个输出带有内容的基本html页面的函数,并在其后面退出。这种方式没有任何其他页面的具体需求(除了功能页面,我猜)。

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

我使用这样的函数被调用时,即使写入数据了,所以我有自己的错误日志...

1

你为什么不只是包含错误信息的脚本?并且要摆脱先前的输出数据,请使用output control将其缓存并将其错误地清除:

if ($error) { 
    ob_clear(); 
    $errorCode = 11; 
    include 'error.php'; 
    exit; 
}