私人網路存取權:推出預檢

Titouan Rigoudy
Titouan Rigoudy
Yifan Luo
Yifan Luo

更新

  • 2022 年 7 月 7 日:更新目前狀態並新增 IP 位址空間定義。
  • 2022 年 4 月 27 日:更新時間表公告。
  • 2022 年 3 月 7 日:在 Chrome 98 中發現問題後,我們宣布將回溯。

簡介

Chrome 將淘汰「私人網路存取權」(PNA) 規格,不再允許從公開網站直接存取私人網路端點。

Chrome 會在任何子資源的私人網路要求之前,開始傳送 CORS 預檢要求,要求取得目標伺服器的明確權限。這項預先檢查要求會攜帶新的標頭 Access-Control-Request-Private-Network: true,而回應必須攜帶對應的標頭 Access-Control-Allow-Private-Network: true

目的是保護使用者免於遭受跨網站偽造要求 (CSRF) 攻擊,鎖定私人網路上的路由器和其他裝置。這些攻擊影響了數十萬名使用者,讓攻擊者將他們重新導向至惡意伺服器。

推出計畫

Chrome 將分兩階段推出這項變更,讓網站有時間注意到變更,並據此做出調整。

  1. 在 Chrome 104 中:

    • Chrome 實驗會在私人網路子資源要求之前傳送預檢要求。
    • 預先檢查失敗只會在開發人員工具中顯示警告,不會影響私人網路要求。
    • Chrome 會收集相容性資料,並連線至受影響最大的網站。
    • 我們預期這項功能將與現有網站廣泛相容。
  2. 最快在 Chrome 113 中:

    • 「只有」在相容性資料指出變更安全無虞,且我們在必要時直接聯絡時,才會開始執行這項作業。
    • Chrome 會強制執行預檢要求,否則會失敗。
    • 淘汰試用期會同時開始,允許受這個階段影響的網站申請延期。試用期至少為 6 個月。

什麼是私人網路存取權 (PNA)

私人網路存取權 (舊稱 CORS-RFC1918) 會限制網站傳送要求至私人網路上的伺服器的能力。

Chrome 已實作部分規格:自 Chrome 96 起,只有安全內容才能提出私人網路要求。詳情請參閱先前的網誌文章

這項規格也擴充了跨來源資源共用 (CORS) 通訊協定,因此網站現在必須先從私人網路上的伺服器明確要求授予,才能傳送任意要求。

PNA 如何分類 IP 位址及識別私人網路

IP 位址分為三個 IP 位址空間: - public - private - local

本機 IP 位址空間包含 IP 位址,這些 IP 位址可能是 RFC1122 的第 3.2.1.3 節所定義的 IPv4 迴轉式位址 (127.0.0.0/8),或是 RFC4291 的第 2.5.3 節所定義的 IPv6 迴轉式位址 (::1/128)。

私人 IP 位址空間包含僅在目前網路內有意義的 IP 位址,包括 RFC1918 中定義的 10.0.0.0/8172.16.0.0/12192.168.0.0/16RFC3927 中定義的連結本機位址 169.254.0.0/16RFC4193 中定義的獨特本機 IPv6 單播位址 fc00::/7RFC4291 的第 2.5.6 節中定義的連結本機 IPv6 單播位址 fe80::/10,以及 IPv4 對應 IPv6 位址,其中對應的 IPv4 位址本身為私人位址。

公開 IP 位址空間包含所有未提及的其他位址。

系統會將本機 IP 位址視為比私人 IP 位址更私密的私人 IP 位址,因此視為比公開 IP 位址更私密。

如果較可用的網路傳送要求給較不可用的網路,要求就會不公開。
私人網路存取 (CORS-RFC1918) 中的公開、私人、本機網路關係

詳情請參閱需要的意見回饋:私人網路 (RFC1918) 的 CORS

預檢要求

背景

預檢要求是 跨來源資源共享 (CORS) 標準引進的機制,可在向目標網站傳送可能產生副作用的 HTTP 要求前,先向該網站要求權限。這可確保目標伺服器瞭解 CORS 通訊協定,並大幅降低 CSRF 攻擊的風險。

權限要求會以 OPTIONS HTTP 要求的形式傳送,並附上特定的 CORS 要求標頭,說明即將傳送的 HTTP 要求。回應必須包含明確同意下一個要求的特定 CORS 回應標頭

代表 CORS 預先檢查的流程圖。系統會將 OPTIONS HTTP 要求傳送至目標,並傳回 200 OK。接著傳送 CORS 要求標頭,並傳回 CORS 回應標頭

私人網路存取權的新功能

系統會為預檢要求引入一對新的要求和回應標頭:

  • 已針對所有 PNA 預檢要求設定 Access-Control-Request-Private-Network: true
  • 必須在所有 PNA 預先飛行回應中設定 Access-Control-Allow-Private-Network: true

不論要求方法和模式為何,所有私人網路要求都會傳送 PNA 預檢要求。這些資訊會在 cors 模式、no-cors 和所有其他模式中,提前傳送給要求。這是因為所有私人網路要求都可能用於 CSRF 攻擊,無論要求模式為何,以及回應內容是否會提供給發起端。

如果目標 IP 位址比發起者更私密,也會對相同來源的要求傳送 PNA 預檢要求。這與一般 CORS 不同,因為預檢要求僅適用於跨來源要求。針對相同來源的要求發出預先檢查要求,可防範DNS 重新綁定攻擊。

範例

可觀察的行為取決於要求的模式

無 CORS 模式

假設 https://foo.example/index.html 嵌入 <img src="https://bar.example/cat.gif" alt="dancing cat"/>,而 bar.example 會解析為 192.168.1.1,這是根據 RFC 1918 的私人 IP 位址。

Chrome 會先傳送預檢要求:

HTTP/1.1 OPTIONS /cat.gif
Origin: https://foo.example
Access-Control-Request-Private-Network: true

如要讓這項要求成功,伺服器必須傳回以下內容:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Private-Network: true

接著,Chrome 會傳送實際要求:

HTTP/1.1 GET /cat.gif
...

伺服器可以正常回應。

CORS 模式

假設 https://foo.example/index.html 執行下列程式碼:

await fetch('https://bar.example/delete-everything', {
  method: 'PUT',
  credentials: 'include',
})

再次說明 bar.example 解析為 192.168.1.1

Chrome 會先傳送預檢要求:

HTTP/1.1 OPTIONS /delete-everything
Origin: https://foo.example
Access-Control-Request-Method: PUT
Access-Control-Request-Credentials: true
Access-Control-Request-Private-Network: true

為了讓這項要求成功,伺服器必須傳回以下內容:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Credentials: true
Access-Control-Allow-Private-Network: true

接著,Chrome 會傳送實際要求:

HTTP/1.1 PUT /delete-everything
Origin: https://foo.example

伺服器可根據一般 CORS 規則回應:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://foo.example

如何判斷網站是否受到影響

自 Chrome 104 起,如果偵測到私人網路要求,系統會先傳送預檢要求。如果這項預先檢查要求失敗,系統仍會傳送最終要求,但 DevTools 問題面板會顯示警告。

開發人員工具「Issues」面板中顯示的失敗的預先檢查要求警告。這項資訊指出:
   請確保私人網路要求只會傳送至允許這類要求的資源,並提供特定要求的詳細資料,以及列出的受影響資源。

您也可以在網路面板中查看及診斷受影響的預檢要求:

在 DevTools 網路面板中,針對 localhost 的失敗預先檢查要求會傳回 501 狀態。

如果您的要求會在沒有私人網路存取權規則的情況下觸發一般 CORS 預檢,網路面板中可能會顯示兩次預檢,且第一個預檢一律會顯示為失敗。這是已知錯誤,您可以放心忽略。

在開發人員工具「網路」面板中,預檢要求在成功執行前出現錯誤。

如要查看強制執行預先檢查成功的結果,您可以從 Chrome 98 開始傳遞下列命令列引數

--enable-features=PrivateNetworkAccessRespectPreflightResults

任何失敗的預先檢查要求都會導致擷取失敗。這樣一來,您就可以測試網站是否能在第二階段的推出計畫後正常運作。您可以使用上述的開發人員工具面板,以與警告相同的方式診斷錯誤。

網站受到影響時的處理方式

這項異動在 Chrome 104 推出時,不會導致任何網站發生問題。不過,我們強烈建議您更新受影響的要求路徑,確保網站可以照常運作。

我們提供兩種解決方案:

  1. 在伺服器端處理預檢要求
  2. 透過企業政策停用 PNA 檢查

在伺服器端處理預檢要求

更新所有受影響擷取的目標伺服器,以便處理 PNA 預先飛行檢查要求。首先,請在受影響的路徑上實作標準 CORS 預先檢查要求的支援功能。接著,新增兩個新的回應標頭支援。

當伺服器收到預檢要求 (含有 CORS 標頭的 OPTIONS 要求) 時,應檢查是否有 Access-Control-Request-Private-Network: true 標頭。如果要求中包含這個標頭,伺服器應檢查 Origin 標頭和要求路徑,以及任何其他相關資訊 (例如 Access-Control-Request-Headers),以確保允許的要求是安全的。通常,您應該要允許控制項存取單一來源。

伺服器決定允許要求後,應以必要的 CORS 標頭和新的 PNA 標頭回應 204 No Content (或 200 OK)。這些標頭包括 Access-Control-Allow-OriginAccess-Control-Allow-Private-Network: true,以及其他必要的標頭。

如需具體情況,請參閱範例

使用企業政策停用私人網路存取檢查

如果您對使用者擁有管理控制權,可以使用下列任一政策停用私人網路存取權檢查:

詳情請參閱「瞭解 Chrome 政策管理」。

提供意見

如果您代管的網站位於私人網路內,且會要求公用網路發出要求,Chrome 團隊對相關意見和用途有興趣。請前往 crbug.com 向 Chromium 回報問題,並將元件設為 Blink>SecurityFeature>CORS>PrivateNetworkAccess

後續步驟

接下來,Chrome 將擴大私人網路存取權檢查,涵蓋網頁工作站:專用工作站、共用工作站和服務工作站。我們暫時預計在 Chrome 107 開始顯示警告。

然後,Chrome 會將私人網路存取權檢查範圍擴大,以涵蓋 iframe 和彈出式視窗等瀏覽作業。我們暫時預計在 Chrome 108 開始顯示警告。

在這兩種情況下,我們將謹慎地採取類似的階段推出方式,讓網頁程式開發人員有時間調整和預估相容性風險。

特別銘謝

封面相片來源:Mark OlsenUnsplash 網站上提供。