Learning Objectives
- 說明 TLS 提供的機密性、完整性與身分驗證,以及它不能保證的事項
- 比較 HTTP 與 HTTPS 在網路上可被觀察到的內容
- 依憑證鏈、名稱與有效期間判斷憑證驗證的結果
- 設定 Cookie 的 Secure 屬性與 HSTS,並說明它們的作用與限制
TLS 提供的三項性質
學生在校園無線網路上登入選課系統,表單送出的帳號與密碼會經過基地台、路由器與數個網路業者。若使用 HTTP,這些內容都是明文,同一路徑上能夠擷取封包的人都看得到。
TLS(Transport Layer Security)組合了第 3 課的元件。TLS 1.3 的規格(RFC 8446)列出三項性質:
| 性質 | 意義 | 使用的技術 |
|---|---|---|
| 身分驗證 | 伺服器一定經過驗證,用戶端可選擇性驗證 | 憑證與數位簽章 |
| 機密性 | 連線建立後的資料只有兩端看得到 | 金鑰交換與對稱加密 |
| 完整性 | 資料被修改時能被偵測 | 已驗證的加密模式 |
HTTPS 是在 TLS 之上傳送 HTTP。下方練習比較同一個登入請求在 HTTP 與 HTTPS 下,路徑上的觀察者看到的內容。
本課的模擬環境。 封包內容由程式產生,網站與帳號都是虛構的,不會擷取任何真實的網路流量。對未獲授權的網路進行擷取可能觸犯法律(第 1 課)。
憑證鏈與 HTTPS 的限制
第 3 課提到,簽章要有公鑰才能驗證,而公鑰必須確認屬於對方。憑證把網域名稱與公鑰綁在一起,並由憑證機構(CA)簽章。瀏覽器與作業系統內建一份受信任的根憑證清單,驗證時沿著憑證鏈向上檢查:
- 網站憑證由中繼 CA 簽發,中繼 CA 由根 CA 簽發,每一層簽章都要正確
- 憑證上的名稱要符合連線的網域
- 憑證要在有效期間內
CA 簽發憑證之前會驗證申請者對網域的控制權。為了發現錯誤或不當簽發的憑證,新簽發的憑證會記錄到公開、只能附加的日誌,這稱為憑證透明度(Certificate Transparency),網域擁有者可以查核是否有他人替自己的網域取得憑證。
HTTPS 不代表網站內容可信。 網域驗證只證明申請者控制這個網域。詐騙網站同樣可以替自己的網域取得憑證,瀏覽器也會正常顯示安全連線。HTTPS 也不保護伺服器或使用者電腦上的資料:伺服器若有 SQL 注入(第 7 課),透過 HTTPS 傳送的注入語句同樣有效。
HSTS、Secure Cookie 與常見設定錯誤
啟用 TLS 之後,仍有幾個環節可能讓資料以明文傳送。
HSTS(HTTP Strict Transport Security)是一個回應標頭,要求瀏覽器在一段時間內只以 HTTPS 連線到這個網域:
Strict-Transport-Security: max-age=31536000; includeSubDomains
瀏覽器記住之後,會自動把 http 網址改為 https;連線遇到憑證錯誤時,也不再提供略過的選項。HSTS 有一個限制:瀏覽器第一次連線之前還不知道這項政策,這次請求可能遭到攻擊。預載清單(preload list)可以補上這個空窗。瀏覽器只接受經由 HTTPS 傳送的 HSTS 標頭。includeSubDomains 會套用到所有子網域,部署前要確認它們都支援 HTTPS;瀏覽器在 max-age 期間會持續記住政策,可以先以較短的時間測試。
Cookie 的 Secure 屬性要求 Cookie 只在 https 請求中傳送(localhost 例外,所以下方在本機環境的模擬瀏覽器仍會送出)。它防止 Cookie 在明文連線中外流,但不防止端點上的讀取:沒有 HttpOnly 時,頁面的 JavaScript 仍可讀取(第 6、8 課)。
混合內容是指 HTTPS 頁面載入 HTTP 資源。瀏覽器會把圖片、音訊、影片這類可升級的請求自動改為 HTTPS;腳本、樣式表、iframe、fetch 等請求則直接封鎖,因為它們能影響整個頁面。
依 OWASP TLS Cheat Sheet,常見的設定錯誤包括:
| 設定錯誤 | 問題 | 建議 |
|---|---|---|
| 啟用 TLS 1.0、1.1 或 SSL | 已被棄用的舊協定 | 預設 TLS 1.3,必要時支援 TLS 1.2 |
| 允許不加密(NULL)、匿名(不驗證伺服器)、匯出級或 RSA 金鑰傳輸的密碼套件 | 沒有加密、沒有驗證身分、強度不足或缺乏前向保密 | 使用 AEAD 與臨時金鑰交換 |
| 部分頁面或資源使用 HTTP | 混合內容,Cookie 可能外流 | 全站 HTTPS,將 HTTP 轉向 HTTPS |
Cookie 未設定 Secure,或未送出 HSTS |
存在以明文連線的機會 | 設定 Secure 並送出 HSTS |
| 多個信任等級不同的系統共用萬用字元憑證的私鑰 | 一處失守影響全部 | 萬用字元憑證只在必要時使用 |
| TLS 函式庫過舊 | 可能存在已知漏洞 | 持續更新(第 18 課) |
用戶端程式也可能出錯:以 Python requests 呼叫 API 時設定 verify=False,等於放棄身分驗證,連線將無法抵抗第 3 課的中間人攻擊。
重點整理
- TLS 提供身分驗證、機密性與完整性;HTTPS 是 TLS 之上的 HTTP
- 使用 HTTPS 時,路上的觀察者仍看得到 IP 位址,未使用 Encrypted Client Hello(ECH)時也看得到 SNI 中的網站名稱;看不到路徑、內容與 Cookie
- 瀏覽器沿著憑證鏈驗證到受信任的根憑證,並檢查名稱與有效期間,驗證失敗時會顯示警告;伺服器應送出完整的憑證鏈,部分瀏覽器會自行補上中繼憑證,其他用戶端則可能失敗
- HTTPS 不代表網站內容可信:網域驗證只證明對網域的控制權,也不保護伺服器上的資料
- HSTS 要求瀏覽器一律使用 HTTPS,但首次連線之前無效;
Secure限制 Cookie 只經 https 傳送,不防止 JavaScript 讀取 - 預設使用 TLS 1.3,停用舊協定,並持續更新函式庫
下一課討論認證:如何確認登入的人是帳號的本人。
小測驗
網址列顯示安全連線,網域是 campus.example.other.example。下列何者正確?
Cookie 設定了 Secure 屬性,能帶來什麼保護?
網站已送出 HSTS 標頭,下列哪一種情況仍然無法由這個標頭保護?
HTTPS 頁面以 <script src="http://cdn.campus.example/app.js"> 載入腳本,瀏覽器的處理方式是什麼?
選課系統已全站使用 HTTPS 與 TLS 1.3。下列哪一種攻擊仍可能成功?