在 PHP 中发出 HSTS 标头有问题吗?

信息安全 tls http hsts
2021-08-15 10:22:17

我想在我的博客上试用 HSTS 政策,但最初没有在网站范围内启用它。由于 HSTS 策略只是一个 HTTP 响应标头,因此在 PHP 中发送标头会有任何问题,如下所示:

header("strict-transport-security: max-age=600");

该站点会将任何 http:// 请求重定向到 https:// ,我意识到这可能会导致 HSTS 标头通过 http:// 发送,而这是不应该的。但是,为了符合 HSTS,用户代理应该忽略通过 http:// 传递的 HSTS 策略,因为它可能已被恶意注入。由于这仅用于测试目的,因此我并不过分担心。

这将允许我仅在特定页面上发布标题并仅将其公开给我自己,而不会影响任何其他用户。我也可以有另一个页面来禁用 HSTS 策略,如下所示:

header("strict-transport-security: max-age=0");

如果这被证明是成功的,以这种方式发布 HSTS 政策是否存在任何问题?也许共享主机上的用户或没有访问/知识来配置响应标头的用户仍然可以以这种方式实现 HSTS。

2个回答

通过从 HTTPS 响应返回标头来启用 HSTS strict-transport-security- 浏览器不关心这是由 PHP、服务器还是负载平衡器设置的 - 只要它通过 HTTPS 接收到有效的标头,就会启用 HSTS。

您也应该可以只从单个页面返回此标头进行测试。RFC 6797状态

如果 UA 通过安全通道从已知 HSTS 主机接收 HTTP 响应,但响应缺少 STS 头字段,则 UA 必须继续将该主机视为已知 HSTS 主机,直到知道该已知的 max-age 值已到达 HSTS 主机。

因此,您的其他没有标题的回复不会取消您网站的 HSTS。

设置max-age=0也是为您的站点取消 HSTS 的正确方法(每个接收用户代理)。我发现的唯一不标准的事情是您正在通过 HTTP 发送标头 - 尽管这会被兼容的用户代理忽略它是无效的,所以我会确保只传输这个当连接安全时(最好遵守我发现的尽可能接近的标准)。

您可以使用以下代码检查是否发出标头,以检查页面是否已通过 HTTPS 访问

<?php
function isSSL(){
 
    if($_SERVER['https'] == 1) /* Apache */ {
        return TRUE;
    } elseif ($_SERVER['https'] == 'on') /* IIS */ {
        return TRUE;
    } elseif ($_SERVER['SERVER_PORT'] == 443) /* others */ {
        return TRUE;
    } else {
        return FALSE; /* just using http */
    }
 
}
?>

HSTS 标头用于域(或子域,如果与includeSubDomain指令一起提供)。但是,值 0 inmax-age将导致用户代理停止使用 HSTS。(请参阅草案规范的第 6.1.1 节。)