这种方法是否足够好/安全,足以向用户显示错误? - PHP

发布于 2024-07-14 09:11:20 字数 623 浏览 4 评论 0原文

我正在开发一个网站,由于用户输入或其他原因,我需要显示一些错误消息。 为此,我有一个名为 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 执行此操作,

谢谢

I'm developing a website, and due to user-input or by other reason, I need to show some error messages.
For this, I have a page named error.php, and I get the error number using $_GET. All error messages are stored in a array.

Example:

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

But I don't want the users to the enter the error code in the URL and see all the other error messages.
For preventing that, I thought I could whitelist the referer page, and only show the error message if the referer is found in my whitelist.

It should be fair similar to this (haven't tested yet ;) )

$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];}

Is this method good enough to avoid the spy-users?

I'm doing this with PHP5

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

天赋异禀 2024-07-21 09:11:21

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

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

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

You shouldn't use an external redirect to get to an error page. How I structure my PHP is like this:

I have a common file that's included in every page, with common functions: handle login/logout, set up constants and the like. Have an error() function there you can pass error information to that will show an error page and exit. An alternative is to use the index.php?include=pagename.php idiom to achieve common functionality but I find this far more flaky and error prone.

If you externally redirect the client (which you obviously need to do sometimes) never rely on the information passed via that mechanism. Like all user input it's inherently untrustworthy and should be sanitized and treated with extreme caution. Don't use cookies either (same problem). Use sessions if you need to persist information between requests.

谁的新欢旧爱 2024-07-21 09:11:21

HTTP_REFERER 可能会被那些有足够动机的人轻易欺骗(telnet 是那里选择的工具),因此不应该被信任。

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

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

$errors[A_VERY_FATAL_ERROR] => "308dj10ijd"

HTTP_REFERER can be spoofed trivially by those with enough incentives (telnet is the tool of choice there), and shouldn't be trusted.

Error messages should never reveal anything critical anyhow, so I'd suggest you to design your error messages in such a way that they can be showed to anyone.

That, or use random hashes to identify errors (instead of 11, use 98d1ud109j2, etc), that would be stored in a central place in an associative array somewhere:

$errors[A_VERY_FATAL_ERROR] => "308dj10ijd"
吖咩 2024-07-21 09:11:21

为什么不直接包含错误消息脚本? 要删除以前的输出数据,请使用 输出控件缓冲它并在错误时清除它:

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

Why don’t you just include the error message script? And to get rid of previous output data, use the output control to buffer it and clear it on error:

if ($error) {
    ob_clear();
    $errorCode = 11;
    include 'error.php';
    exit;
}
叫嚣ゝ 2024-07-21 09:11:21

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

RedirectMatch 404 ^error-pages/*$

并且在错误页面内您可以拥有显示错误的可包含页面。

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

Instead of redirecting to an error page why not include an error page. You can restrict access to a directory containing the php files that contain the error content with .htaccess:

RedirectMatch 404 ^error-pages/*$

and inside the error-pages you can have include-able pages which display errors.

With this method you can be sure that no one can directly access the pages in the error-pages directory yet you can still include them within scripts that are publicly accessible.

猫腻 2024-07-21 09:11:21

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

很简单,就是检查是否有问题,如果有问题,调用该函数即可。

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

If you handle errors before sending headers, you can easily create a function that outputs a basic html page with content, and exit right after it. That way there is no specific need for any other page (apart from the functions page, I guess).

It's as simple as checking if there's a problem, and if there is a problem, just call the function.

I use a function like this that even writes data away when it is called, so I have my own error logs...

少跟Wǒ拽 2024-07-21 09:11:20

不,它不是远程安全的:HTTP Referer 标头很容易被欺骗,而且也不是必需的标头。 我建议您阅读这篇文章以获取利用代码的示例(用 PHP 编写),或者下载 此 Firefox 插件,让您可以轻松地自行完成此操作自己的浏览器。

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

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

总结一下:您不能无需身份验证即可限制对任何公共网络资源的访问。

No, it isn't remotely secure: the HTTP Referer header is trivial to spoof, and is not a required header either. I suggest you read this article for an example of exploiting code (written in PHP), or download this add-on for Firefox to do it yourself from the comfort of your own browser.

In addition, your $allowedReferer array should contain full URL's, not just the script name, otherwise the code will also be exploitable from remote referrals, e.g. from

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

To summarise: you cannot restrict access to any public network resource without requiring authentication.

失而复得 2024-07-21 09:11:20

您可以简单地“就地”显示错误,而不是重定向 - 例如,就像使用类似的内容调整当前代码一样简单。

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 可以检查提供的哈希值是否已正确创建。 如果是,那么它很可能是由您的代码创建的,而不是由用户创建的。

Rather than redirect, you could simply display the error "in place" - e.g. something as simple as adapting your present code with something like

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

In practice it might be a little more sophisticated, but the idea is the same - the user is presented with an error message without redirecting. Make sure you output some kind of error header, e.g. header("HTTP/1.0 401 Bad Request") to tell the browser that it's not really seeing the requested page.

If you do want to redirect, then you could create a "tamperproof" URL by including a hash of the error number with a salt known only to your code, e.g.

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

Now your error.php can check whether the supplied hash was correctly created. If it was, then in all likelihood it was created by your code, and not the user.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文