SERVER ['HTTP

我做了很多搜索,并且还阅读了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']以及为什么你不应该在form action属性中使用它而没有正确的转义以防止XSS攻击。

    关于我上面的原始问题的结论是,对于站点上的所有链接使用$_SERVER['HTTP_HOST']而不必担心XSS攻击是“安全的”,即使在表单中使用时也是如此。

    如果我错了,请纠正我。


    这可能是每个人的第一个想法。 但这有点困难。 请参阅Chris Shiflett的文章SERVER_NAMEHTTP_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;
    }
    

    另外需要注意的是,如果服务器运行在80以外的端口上(如开发/内联网机器上常见的那样),那么HTTP_HOST包含端口,而SERVER_NAME则不包含端口。

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

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

    正如Mike在下面指出的那样,在HTTPS上运行时, HTTP_HOST不包含:443 (除非您运行的是非标准端口,而我没有测试过)。


    这是Symfony用于获取主机名的详细翻译(参见第二个示例以获得更直接的翻译):

    function getHost() {
        $possibleHostSources = array('HTTP_X_FORWARDED_HOST', 'HTTP_HOST', 'SERVER_NAME', 'SERVER_ADDR');
        $sourceTransformations = array(
            "HTTP_X_FORWARDED_HOST" => function($value) {
                $elements = explode(',', $value);
                return trim(end($elements));
            }
        );
        $host = '';
        foreach ($possibleHostSources as $source)
        {
            if (!empty($host)) break;
            if (empty($_SERVER[$source])) continue;
            $host = $_SERVER[$source];
            if (array_key_exists($source, $sourceTransformations))
            {
                $host = $sourceTransformations[$source]($host);
            } 
        }
    
        // Remove port number from host
        $host = preg_replace('/:d+$/', '', $host);
    
        return trim($host);
    }
    

    已过期:

    这是我翻译为在PHP中使用Symfony框架中使用的一种方法,它尝试按照最佳实践的顺序从各种方式获取主机名:

    function get_host() {
        if ($host = $_SERVER['HTTP_X_FORWARDED_HOST'])
        {
            $elements = explode(',', $host);
    
            $host = trim(end($elements));
        }
        else
        {
            if (!$host = $_SERVER['HTTP_HOST'])
            {
                if (!$host = $_SERVER['SERVER_NAME'])
                {
                    $host = !empty($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '';
                }
            }
        }
    
        // Remove port number from host
        $host = preg_replace('/:d+$/', '', $host);
    
        return trim($host);
    }
    
    链接地址: http://www.djcxy.com/p/42251.html

    上一篇: SERVER['HTTP

    下一篇: Linq2Sql Many:Many question, How would you do this?