为了账号安全,请及时绑定邮箱和手机立即绑定

PHP $ _SERVER ['HTTP_HOST']与$ _SERVER

/ 猿问

PHP $ _SERVER ['HTTP_HOST']与$ _SERVER

哔哔one 2019-08-30 16:17:16

我做了很多搜索,还阅读了PHP $ _SERVER文档。对于在我的网站中使用的简单链接定义,我的PHP脚本使用哪个权限?


$_SERVER['SERVER_NAME'] 是基于您的Web服务器的配置文件(在我的情况下是Apache2),并根据一些指令而变化:(1)VirtualHost,(2)ServerName,(3)UseCanonicalName等。


$_SERVER['HTTP_HOST'] 基于客户的要求。


因此,在我看来,为了使我的脚本尽可能兼容而使用的正确方法是$_SERVER['HTTP_HOST']。这个假设是否正确?


后续评论:


我想在读完这篇文章之后我有点偏执,并注意到有些人说“他们不会相信任何一个$_SERVER变种”:


http://markjaquith.wordpress.com/2009/09/21/php-server-vars-not-safe-in-forms-or-links/


http://php.net/manual/en/reserved.variables.server.php#89567(评论:Vladimir Kornea 14-Mar-2009 01:06)


显然,讨论主要是关于$_SERVER['PHP_SELF']为什么你不应该在表单action属性中使用它而没有适当的转义以防止XSS攻击。


我对上述原始问题的结论是$_SERVER['HTTP_HOST'],即使在表单中使用,也可以“安全”地使用网站上的所有链接,而不必担心XSS攻击。


如果我错了,请纠正我。


查看完整描述

3 回答

?
浮云间

使用其中之一 它们同样(安全),因为在许多情况下,SERVER_NAME只是从HTTP_HOST填充。我通常会使用HTTP_HOST,以便用户保持他们开始的确切主机名。例如,如果我在.com和.org域中拥有相同的站点,我不想将.org中的某人发送到.com,特别是如果他们可能在.org上有登录令牌,那么如果他们被发送到另一个域名。


无论哪种方式,您只需要确保您的webapp只会响应已知良好的域名。这可以通过以下方式完成:(a)使用Gumbo的应用程序端检查,或者(b)使用您想要的域名上的虚拟主机,该主机不响应给出未知主机头的请求。


这样做的原因是,如果您允许以任何旧名称访问您的站点,您可以对DNS重新绑定攻击(其他站点的主机名指向您的IP,用户使用攻击者的主机名访问您的站点,然后是主机名)移动到攻击者的IP,带上你的cookie / auth)和搜索引擎劫持(攻击者在你的站点指出他们自己的主机名,并试图让搜索引擎将其视为'最佳'主要主机名)。


显然,讨论主要是关于$ _SERVER ['PHP_SELF']以及为什么你不应该在表单action属性中使用它而没有适当的转义以防止XSS攻击。


Pfft。好吧,你不应该在没有转义的情况下使用任何属性中的任何东西,所以那里的服务器变量没什么特别的。htmlspecialchars($string, ENT_QUOTES)


查看完整回答
反对 回复 2019-08-30
?
红颜莎娜

这可能是每个人的第一个想法。但这有点困难。请参阅Chris Shiflett的文章SERVER_NAMEVersusHTTP_HOST。


似乎没有银弹。只有当您强制Apache使用规范名称时,您才能获得正确的服务器名称SERVER_NAME。


所以你要么使用它,要么根据白名单检查主机名:


$allowed_hosts = array('foo.example.com', 'bar.example.com');

if (!isset($_SERVER['HTTP_HOST']) || !in_array($_SERVER['HTTP_HOST'], $allowed_hosts)) {

    header($_SERVER['SERVER_PROTOCOL'].' 400 Bad Request');

    exit;

}


查看完整回答
反对 回复 2019-08-30
?
慕雪6173905

只是另外一个注意事项 - 如果服务器在80以外的端口上运行(在开发/内联网机器上可能是常见的),则HTTP_HOST包含端口,而不包含端口SERVER_NAME。


$_SERVER['HTTP_HOST'] == 'localhost:8080'

$_SERVER['SERVER_NAME'] == 'localhost'

(至少这是我在基于Apache端口的虚拟主机中注意到的)


正如迈克下面提到的,HTTP_HOST并没有包含:443在HTTPS运行时(除非你是一个非标准端口,我没有测试运行)。


查看完整回答
反对 回复 2019-08-30

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信