$_SERVER['HTTP_HOST']
即使在表单中使用,也不必担心 XSS 攻击,用于网站上的所有链接是否“安全” ?
是的,只要您在接受它们之前验证它们,就可以安全地使用$_SERVER['HTTP_HOST']
, (甚至$_GET
and $_POST
) 。这就是我为安全生产服务器所做的:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
$reject_request = true;
if(array_key_exists('HTTP_HOST', $_SERVER)){
$host_name = $_SERVER['HTTP_HOST'];
// [ need to cater for `host:port` since some "buggy" SAPI(s) have been known to return the port too, see http://goo.gl/bFrbCO
$strpos = strpos($host_name, ':');
if($strpos !== false){
$host_name = substr($host_name, $strpos);
}
// ]
// [ for dynamic verification, replace this chunk with db/file/curl queries
$reject_request = !array_key_exists($host_name, array(
'a.com' => null,
'a.a.com' => null,
'b.com' => null,
'b.b.com' => null
));
// ]
}
if($reject_request){
// log errors
// display errors (optional)
exit;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
echo 'Hello World!';
// ...
的优点$_SERVER['HTTP_HOST']
是它的行为比$_SERVER['SERVER_NAME']
. 对比➫➫:
主机内容:当前请求的标头(如果有)。
和:
当前脚本在其下执行的服务器主机的名称。
使用定义更好的接口 $_SERVER['HTTP_HOST']
意味着更多的 SAPI 将使用可靠的定义良好的行为来实现它。(与其他不同。)但是,它仍然完全依赖于 SAPI ➫➫:
无法保证每个 Web 服务器都会提供这些 [$_SERVER
条目] 中的任何一个;服务器可能会省略一些,或提供此处未列出的其他内容。
要了解如何正确检索主机名,首先您需要了解仅包含代码的服务器无法知道(验证的先决条件)其在网络上的名称。它需要与为其提供自己名称的组件交互。这可以通过以下方式完成:
本地配置文件
本地数据库
硬编码源代码
外部请求 ( curl )
客户端/攻击者的Host:
请求
ETC
通常它通过本地(SAPI)配置文件完成。请注意,您已正确配置它,例如在 Apache ➫➫中:
需要“伪造”一些东西才能使动态虚拟主机看起来像一个正常的主机。
最重要的是 Apache 用来生成自引用 URL 等的服务器名称。它是用ServerName
指令配置的,它可以通过SERVER_NAME
环境变量提供给 CGI。
运行时使用的实际值由UseCanonicalName 设置控制。
UseCanonicalName Off
服务器名称来自请求中标头的内容Host:
。它 UseCanonicalName DNS
来自虚拟主机 IP 地址的反向 DNS 查找。前者用于基于名称的动态虚拟主机,后者用于**基于 IP 的主机。
如果Apache 由于没有Host:
标头或 DNS 查找失败而无法计算出服务器名称,则使用配置的值ServerName
代替。