第一個請求問題
HTTPS 在建立連線後對流量進行加密,但對 HTTP URL 的初始請求仍以明文形式傳送。同網路上的攻擊者可以攔截第一個請求,執行 SSL 分割攻擊,將使用者在整個會話中降級為 HTTP。
HTTP 嚴格傳輸安全性 (HSTS) 會關閉此視窗。一旦瀏覽器收到 HSTS 標頭,它就會自動將所有未來的 HTTP 請求升級為 HTTPS,並在憑證無效時拒絕連線。
HSTS 的工作原理
伺服器在 HTTPS 回應中傳送 Strict-Transport-Security 標頭:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
| 指令 | 描述 |
|---|---|
| 佔位符_0 | 瀏覽器應記得只使用 HTTPS 多久 |
| 佔位符_0 | 將政策套用至所有子域 |
| 佔位符_0 | 瀏覽器預裝清單包含訊號 |
處理後,瀏覽器:
1.將網域的所有http://連結改寫為https://
2.如果TLS握手失敗或無效,則拒絕連接
3. 在 max-age 的持續時段緩存策略
在伺服器上設定 HSTS
NGINX
server {
listen 443 ssl;
ssl_certificate /etc/ssl/certs/example.pem;
ssl_certificate_key /etc/ssl/private/example.key;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}
即使在錯誤頁面上染色體傳送標頭,「始終」參數也能確保。
###阿帕契
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
###雲耀
Cloudflare 穿透儀表板實現 HSTS:SSL/TLS > 邊緣權限 > HTTP 嚴格傳輸安全性。您可以一鍵切換預先載入和 includeSubDomains。 Cloudflare 也提供 「No Sniff」 模式,可防止邊緣的降級攻擊。
Express/Node.js
const helmet = require("helmet");
app.use(helmet.hsts({
maxAge: 31536000,
includeSubDomains: true,
preload: true
}));
HSTS 預先載入列表
max-age 指令僅在使用者造訪您的網站一次後才會相容。 HSTS 預先載入清單嵌入到 Chrome、Firefox、Safari 和 Edge 中,始終對應使用 HTTPS 的網域進行硬編碼,從而完全消除了第一次請求漏洞。
若要提交您的網域:
1.確保您的網站返回帶有 preload 的有效 HSTS 標頭
2. 前往hstspreload.org
3. 提交您的域名
包含預載的要求:
| 要求 | 詳情 |
|---|---|
| 有效資源 | 所有子網域上的 TLS |
| 佔位符_0 | 至少 31536000(1 年) |
| 佔位符_0 | 必填 |
| 佔位符_0 | 出現在標題 |
| 方向 | HTTP → HTTPS 適用於所有請求 |
**警告:**預先載入包含對於網域來說是永久的。一旦接受,您就無法輕易地從清單中刪除您的網域。
測試 HSTS 部署
有幾個工具可以驗證您的 HSTS 配置:
# curl with headers
curl -sI https://example.com | grep -i strict-transport
# Security Headers
# https://securityheaders.com
# SSL Labs
# https://www.ssllabs.com/ssltest/analyze.html?d=example.com
# Using the HSTS check script
curl -s https://hstspreload.org/api/v2/check?domain=example.com
常見陷阱
| 問題 | 後果 | 修復 |
|---|---|---|
max-age 太短 | 保單頻率重置 | 設定為至少 1 年 |
缺少 includeSubDomains | 子網域不受保護 | 新增指令 |
| 僅 HTTP 網站提供 HSTS | 標題被忽略 | 僅透過 HTTPS 提供服務 |
| 內容 | 瀏覽器阻止不安全混合資源 | 審核所有http://引用 |
| 需要準備即可預先載入 | 永久 HTTPS 需求 | 先使用 max-age=0 測試 |
開發期間清除HSTS
若要清除瀏覽器中緩存的HSTS策略:
- Chrome:
chrome://net-internals/#hsts→ 刪除域名 - Firefox: 清除網域的瀏覽記錄
- Safari: 清除首選項中的網站數據
作為開發人員,使用 max-age=0 來表示策略撤銷:
Strict-Transport-Security: max-age=0
百年
HSTS是基本的安全標頭,可確保在首次存取後始終使用HTTPS,從而防止SSL分割和降級攻擊。使用max-age=31536000、includeSubDomains和任選的preload對其進行配置以實現全面保護。始終使用安全檢查器測試您的配置,並在開發過程中清除HSTS佇列,曼哈頓鎖定。

