隐藏PHP的X-Powered-By头信息

51

我知道在PHP中,可以通过发送X-Powered-By头信息来获取PHP版本。

我还知道,通过附加一些校验和,可以访问PHP的贡献者名单和一些随机图片(更多信息请参见此处)。

我还知道,在php.ini文件中,您可以将expose_php = off来关闭相关功能。

但是有一些我在几个网站上做过的事情,那就是使用:

header('X-Powered-By: Alex');
当我查看标头时,我可以看到它现在是“Alex”,而不是 PHP 版本。我的问题是,这是否会先发送以前的 PHP 标头(在到达我的 header() 之前),并且它是否可以被任何嗅探程序检测到?或者标头是由 PHP 在发送回浏览器之前“收集”的?顺便说一句,这不是为了安全而混淆,只是好奇 PHP 中的标头是如何工作的。

4
为什么没有人建议使用header_remove - Pacerier
8个回答

40
你可以在php.ini中设置expose_php = Off,如果不想发送X-Powered-By标头。
PHP首先编译所有内容(包括哪个标头具有哪些值),然后开始输出,而不是相反。
通过它自己的彩蛋可检测到PHP,你可以在此处阅读有关此主题的信息:PHP彩蛋

PHP文档:https://www.php.net/manual/zh/ini.core.php#ini.expose-php - cachius

30

请参见Apache技巧:隐藏PHP版本(X-Powered-By)

糟糕...我们可以看到PHP添加了自己的标语:

X-Powered-By: PHP/5.1.2-1+b1…

让我们看看如何禁用它。为了防止 PHP 将其签名添加到 Web 服务器标头中,暴露其已安装在服务器上的事实,我们需要在 php.ini 中找到变量 expose_php 并将其设为 off

默认情况下,expose_php 被设置为 On。

在您的 php.ini 中(根据您的 Linux 发行版,可以在各种位置找到,例如 /etc/php.ini、/etc/php5/apache2/php.ini 等),定位包含 expose_php On 的行并将其设置为 Off:

expose_php = Off

进行此更改后,PHP将不再向Web服务器头添加其签名。这样做不会使您的服务器更安全...它只是防止远程主机轻松地看到您在系统上安装了PHP以及您正在运行的版本。


3
但是这只建议在php.ini中将'expose_php = Off'设置为关闭,这正如Alex在他的帖子中提到的。 - Ludwig

18
在PHP中,只有遇到第一个输出语句时头部才会被发送。这包括在第一个<?php之前的任何内容。
这也是为什么如果你尝试在输出内容之后使用setcookie,它会抛出一个警告:

Warning: Cannot modify header information - headers already sent by (output started at /path/to/php/file.php:100) in /path/to/php/file.php on line 150

请注意,如果正在使用输出缓冲,则以上内容均不适用,因为输出将在运行适当的输出缓冲命令之前不会被发送。

5

如果你正在使用共享主机,并且想要隐藏 X-Powered-By: PHP/7.x.x,可以在.htaccess文件中添加以下代码:

Header always unset X-Powered-By
Header unset X-Powered-By

然后重新加载浏览器或使用LiteSpeed Cache插件清除缓存:https://en.wordpress.org/plugins/litespeed-cache/


3

在将内容发送回浏览器之前,PHP会“收集”标头,因此您可以覆盖状态标头等内容。测试的方法是打开命令提示符并输入:

telnet www.yoursite.com 80
GET /index.php HTTP/1.1
[ENTER]
[ENTER]

您将看到响应中发送的标头(在域名后用您的PHP页面的URL替换/index.php)。


1
查看 HTTP 响应头的更简单的方法是使用 curl -I http://hostname/path - David Robertson
1
为什么要使用GET请求而不是HEAD请求? - kyle k
1
@kylek,在处理 Heisenbugs 时,最好同时测试两者。 - Pacerier

3
为了在没有访问php.ini的情况下去除X-Powered-By头部,只需添加一个空头即可。
<?php header('X-Powered-By:'); ?>

这将用空值覆盖默认的X-Powered-By头,大多数客户端和应用程序会像没有发送此头文件一样处理。
如前所述,这必须在发送任何输出之前插入到代码中。
而回答你的问题:
只有你的X-Powered-By头将被发送,因为它被具有相同名称的头文件替换。因此,它不能被“嗅探器”检测到。

它不会删除标题,只是重置其值。 - Pacerier

2
我的问题是,这会在到达我的 header() 之前先发送之前的 PHP 头文件吗?是否可以被任何嗅探程序检测到?还是头信息被 PHP “收集”后一次性发送回浏览器?
不会先发送之前的 PHP 头文件。在 PHP 中,头信息要么发送,要么不发送(作为一个批次完整发送)。默认情况下,您的 headerDocs 调用将使用相同名称替换以前的头文件(除非您使用第二个参数指定其他内容)。 注意:如果 PHP 不收集头信息,它将无法替换一个头信息。
由于它不会提前发送,因此无法使用嗅探程序进行检测。
因此,头信息由 PHP 收集,并在“真正”的输出开始时发送(HTTP 响应主体)。
请参阅 headers_sentDocs

0

PHP内置了一个删除头信息的函数:header_remove()

要删除X-Powered-By头信息,可以使用以下代码:

<?php

header_remove(
    name: 'X-Powered-By'
);

如您所见,您只需将标题名称作为字符串参数传递即可完成。

请注意,name参数不区分大小写,因此您可以使用x-powered-by进行调用。


自PHP 8.0.0以来,在不带name参数调用函数时,所有先前设置的标头都将被取消设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接