0

HSTS响应头缺少includeSubDomains修复:子域名安全漏洞彻底解决方案

2026.05.26 | youres | 13次围观
# HSTS响应头缺少includeSubDomains修复:子域名安全漏洞彻底解决方案 ## 前言 最近在给一个网站做安全响应头配置审计时,发现一个很典型的问题:主域名配置了HSTS,但缺少`includeSubDomains`指令。这个看似小小的遗漏,实际上给整个域名体系留下了一个不小的安全隐患。 今天这篇文章,就是把这个问题的来龙去脉讲清楚,顺便给出完整的修复方案。文章会覆盖Nginx、Apache、IIS等主流Web服务器的配置方法,以及如何验证修复是否生效。 ## 什么是includeSubDomains? 先复习一下HSTS(HTTP Strict Transport Security)的基本原理。HSTS是一个安全响应头,用来告诉浏览器:"这个网站只允许HTTPS连接,不要用HTTP访问我"。 而`includeSubDomains`是HSTS的一个可选指令,它的作用是:**把这条强制HTTPS的规则,也应用到所有的子域名**。 一个标准的、完整的HSTS响应头应该是这样的: ``` Strict-Transport-Security: max-age=31536000; includeSubDomains; preload ``` 三个指令的含义: - `max-age=31536000`:告诉浏览器缓存这个规则31536000秒(1年) - `includeSubDomains`:规则同时适用于所有子域名 - `preload`:同意被加入到浏览器的HSTS预加载列表 ## 缺少includeSubDomains的风险 如果只配置了`max-age`而没有`includeSubDomains`,会出现什么问题? **问题核心:子域名仍然可以通过HTTP访问** 举个例子: - 主域名:`example.com`(配置了HSTS,但没有includeSubDomains) - 子域名:`admin.example.com`(可能根本没有配置HTTPS) 这种情况下: 1. 用户访问 `https://example.com` 后,浏览器会记住这个站点只能用HTTPS 2. 但是访问 `http://admin.example.com` 或者 `https://admin.example.com` 时,浏览器**不会**强制跳转HTTPS 3. 攻击者可以对子域名实施**降级攻击**(Downgrade Attack)或者**cookie劫持** ### 实际攻击场景 假设你的主站 `example.com` 配置了HSTS,但 `api.example.com` 没有: 1. 用户连上了一个恶意WiFi(咖啡厅、机场等) 2. 攻击者作为中间人,拦截了用户发往 `api.example.com` 的请求 3. 即使用户想访问HTTPS版本的API,攻击者也可以把请求降级到HTTP 4. 因为缺少`includeSubDomains`,浏览器不会阻止这个降级行为 5. 攻击者在HTTP明文流量中截获了用户的session cookie或者API token 这个漏洞在现实中被多次利用,特别是在那些有大量子域名的企业应用中。 ## 如何检测是否缺少includeSubDomains? 有三种快速检测方法: ### 方法1:使用curl命令 ```bash curl -I https://example.com ``` 查看响应头中是否有: ``` Strict-Transport-Security: max-age=31536000 ``` 如果看到了HSTS头,但没有`includeSubDomains`,那就是缺少了这个指令。 ### 方法2:使用浏览器开发者工具 1. 打开Chrome/Firefox开发者工具(F12) 2. 切换到Network(网络)标签 3. 访问你的网站 4. 点击第一个请求,查看Response Headers(响应头) 5. 找到`Strict-Transport-Security`这一行 ### 方法3:使用在线检测工具 推荐两个工具: - **Security Headers**(https://securityheaders.com):输入域名,一键检测所有安全响应头 - **Mozilla Observatory**(https://observatory.mozilla.org):更详细的安全评分和建议 这两个工具都会明确指出你的HSTS是否缺少`includeSubDomains`。 ## Nginx修复方法 Nginx的配置非常直接,在`nginx.conf`或者站点配置文件的`server`块中添加: ```nginx server { listen 443 ssl; server_name example.com; # 其他SSL配置... # HSTS配置(包含includeSubDomains) add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # ... } ``` ### 关键点说明 1. **必须加`always`参数**:Nginx的`add_header`指令默认只在成功响应(2xx和3xx)时添加头信息。加上`always`后,错误页面(4xx、5xx)也会返回HSTS头。 2. **HTTP到HTTPS的重定向也要配置**: ```nginx server { listen 80; server_name example.com www.example.com; return 301 https://$server_name$request_uri; } ``` 3. **测试配置是否正确**: ```bash nginx -t ``` 4. **重新加载配置**: ```bash systemctl reload nginx # 或者 nginx -s reload ``` ## Apache修复方法 Apache需要在虚拟主机配置或者`.htaccess`文件中添加: ### 方法1:修改虚拟主机配置(推荐) 在`/etc/apache2/sites-available/your-site.conf`或者`httpd.conf`中: ```apache ServerName example.com # 其他SSL配置... # HSTS配置 Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # ... ``` ### 方法2:使用.htaccess文件 如果你的站点使用`.htaccess`,在网站根目录的`.htaccess`文件中添加: ```apache Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" ``` ### 关键点说明 1. **确保`mod_headers`模块已启用**: ```bash a2enmod headers systemctl restart apache2 ``` 2. **测试Apache配置**: ```bash apache2ctl configtest ``` 3. **重新加载配置**: ```bash systemctl reload apache2 ``` ## IIS修复方法 在IIS中配置HSTS需要通过HTTP响应头设置: ### 方法1:使用IIS管理器(GUI) 1. 打开IIS管理器 2. 选择你的站点 3. 双击"HTTP响应头" 4. 点击"添加" 5. 名称:`Strict-Transport-Security` 6. 值:`max-age=31536000; includeSubDomains; preload` 7. 点击"确定" ### 方法2:修改web.config文件 在站点根目录的`web.config`文件中添加: ```xml ``` ### 方法3:使用PowerShell ```powershell Import-Module WebAdministration Set-WebConfigurationProperty -Filter "system.webServer/httpProtocol/customHeaders" -Name "." -Value @{name="Strict-Transport-Security";value="max-age=31536000; includeSubDomains; preload"} -PSPath "IIS:\Sites\YourSiteName" ``` ## Cloudflare修复方法 如果你使用Cloudflare CDN,可以直接在Cloudflare控制台开启HSTS: 1. 登录Cloudflare控制台 2. 选择你的域名 3. 点击"SSL/TLS" → "边缘证书" 4. 找到"HTTP严格传输安全(HSTS)" 5. 点击"启用HSTS" 6. 勾选"启用includeSubDomains" 7. 设置max-age(建议至少6个月) 8. 如果需要,勾选"启用preload" **注意**:Cloudflare的HSTS配置会覆盖源站的设置,所以如果你在Cloudflare开启了HSTS,源站就不需要再配置了。 ## 如何验证修复是否生效? 修复完成后,一定要验证是否生效。推荐三种验证方法: ### 验证方法1:使用curl ```bash curl -I https://example.com | grep -i strict ``` 应该看到: ``` strict-transport-security: max-age=31536000; includeSubDomains; preload ``` ### 验证方法2:使用浏览器开发者工具 1. 打开开发者工具(F12) 2. 访问你的网站 3. 查看Network标签中的第一个请求 4. 在Response Headers中确认`strict-transport-security`的值 ### 验证方法3:使用Security Headers在线工具 访问 https://securityheaders.com,输入你的域名,点击"Scan"。 在结果页面中,找到HSTS那一栏: - 如果显示绿色,且包含`includeSubDomains`,说明配置正确 - 如果显示黄色或者红色,根据提示进行调整 ## 常见问题与解决方法 ### 问题1:配置了includeSubDomains后,子域名访问不了 **原因**:子域名可能没有配置HTTPS证书,或者证书已过期。 **解决方法**: 1. 为子域名申请SSL证书(可以使用Let's Encrypt免费证书) 2. 确保子域名的HTTPS配置正确 3. 如果子域名暂时无法支持HTTPS,可以分阶段部署: - 第一阶段:只为子域名配置HTTPS,但不开启HSTS - 第二阶段:所有子域名都支持HTTPS后,再添加`includeSubDomains` ### 问题2:includeSubDomains导致preload申请被拒 **原因**:HSTS preload列表要求非常严格,必须确保所有子域名都支持HTTPS。 **解决方法**: 1. 访问 https://hstspreload.org 2. 输入你的域名,查看具体的拒绝原因 3. 根据提示修复问题(通常是某个子域名不支持HTTPS) 4. 修复后重新提交申请 ### 问题3:Nginx配置后不生效 **原因**:可能是`add_header`指令的继承问题。 **解决方法**: 1. 确保在正确的`server`块中配置 2. 如果有多个`add_header`指令,确保它们在同一层级 3. 使用`nginx -T`命令查看最终生效的配置 4. 确认配置文件中没有重复的HSTS头(可能导致冲突) ## 最佳实践建议 根据我的经验,配置HSTS(包含includeSubDomains)时,建议遵循以下最佳实践: ### 1. 分阶段部署 不要一次性在所有子域名上开启`includeSubDomains`,而是分阶段进行: **第一阶段**:测试环境验证 - 在测试环境配置HSTS(max-age设为较小值,比如300秒) - 验证所有功能正常 **第二阶段**:生产环境小范围试点 - 选择一个不太重要的子域名,配置完整的HSTS - 观察是否有问题 **第三阶段**:全量部署 - 所有子域名都支持HTTPS后,在主域名配置`includeSubDomains` - 逐步增大max-age的值,最终设置为1年(31536000秒) ### 2. 使用相同的max-age 确保所有子域名的HSTS `max-age`值相同,避免浏览器缓存不一致导致的问题。 ### 3. 定期检查 建议每个月使用自动化脚本检查一次所有子域名的安全响应头配置,及时发现问题。 可以用这个curl脚本批量检测: ```bash #!/bin/bash domains=("example.com" "www.example.com" "api.example.com" "admin.example.com") for domain in "${domains[@]}"; do echo "Checking $domain..." curl -I -s "https://$domain" | grep -i strict echo "---" done ``` ### 4. 监控HSTS preload状态 如果你的域名在HSTS preload列表中,建议定期检查一下状态: ```bash curl -s "https://hstspreload.org/api/v2/status?domain=example.com" ``` ## 相关文章推荐 如果你对HSTS和安全响应头感兴趣,可以看看这些文章: - [Nginx HSTS配置错误排查:常见原因与解决方法](https://www.youres.cn/?id=776) - 深入讲解HSTS配置中的各种坑 - [如何验证HSTS是否生效:4种方法让你的网站安全策略真正落地](https://www.youres.cn/?id=771) - 多种验证方法详解 - [Nginx安全响应头检查工具推荐:5款实用工具助力网站安全](https://www.youres.cn/?id=768) - 选对工具,事半功倍 ## 总结 HSTS响应头缺少`includeSubDomains`是一个常见但危险的安全配置疏漏。它会导致子域名不受HSTS保护,给攻击者留下可乘之机。 修复方法并不复杂,只需要在HSTS响应头中加上`includeSubDomains`指令即可。但需要注意的是,开启这个选项前,必须确保所有子域名都支持HTTPS,否则会导致子域名无法访问。 建议按照"测试环境验证 → 小范围试点 → 全量部署"的流程来实施,避免一次性改动导致大面积故障。 最后,安全配置不是一劳永逸的事情,建议定期检查、持续优化,确保你的网站始终处于最佳的安全状态。 --- **本文关键词**:HSTS, includeSubDomains, 安全响应头, Nginx, Apache, IIS, 子域名安全, HTTPS强制跳转, 网站安全配置 **版权声明**:本文为youres原创文章,未经允许不得转载。
版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论