对网站上的所有链接使用$_SERVER['HTTP_HOST'] 是否“安全”而不必担心 XSS 攻击,即使在表单中使用也是如此?
是的,使用$_SERVER['HTTP_HOST'] 是safe,(甚至$_GET 和$_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'] 更明确。对比➫➫:
Host 的内容:当前请求的标头,如果有的话。
与:
执行当前脚本的服务器主机名。
使用像$_SERVER['HTTP_HOST'] 这样定义更好的接口意味着更多的SAPI 将使用可靠 定义良好的行为来实现它。 (不像the other。)但是,它仍然完全依赖于SAPI ➫➫:
无法保证每个网络服务器都会提供这些 [$_SERVER 条目];服务器可能会省略一些,或提供此处未列出的其他内容。
要了解如何正确检索主机名,首先您需要了解仅包含代码的服务器无法知道(验证的先决条件)它在网络上拥有自己的名字。它需要与为其提供自己名称的组件交互。这可以通过以下方式完成:
-
本地配置文件
-
本地数据库
-
硬编码源代码
-
外部请求 (curl)
-
客户端/攻击者的Host:请求
-
等
通常通过本地 (SAPI) 配置文件完成。请注意,您已正确配置它,例如在阿帕奇➫➫:
需要“伪造”一些东西才能使动态虚拟主机看起来像一个正常的主机。
最重要的是 Apache 用来生成自引用 URL 等的服务器名称。它是用 ServerName 指令配置的,它可以通过 SERVER_NAME 环境变量提供给 CGI。
运行时使用的实际值由 UseCanonicalName 设置控制。
使用 UseCanonicalName Off 服务器名称来自请求中Host: 标头的内容。 使用 UseCanonicalName DNS 它来自虚拟主机 IP 地址的反向 DNS 查找。前者用于基于名称的动态虚拟主机,后者用于**基于IP的主机。
如果 Apache 无法计算出服务器名称,因为没有Host: 标头或DNS 查找失败然后 使用ServerName 配置的值来代替。