更新
- 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 會分兩階段推出這項變更,讓網站有時間注意到變更並做出調整。
在 Chrome 104 中:
- Chrome 實驗會在私人網路子資源要求之前傳送預檢要求。
- 預先檢查失敗只會在開發人員工具中顯示警告,不會影響私人網路要求。
- Chrome 會收集相容性資料,並聯絡受影響最大的網站。
- 我們預期這項功能將與現有網站廣泛相容。
最快在 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/8
、172.16.0.0/12
和 192.168.0.0/16
、RFC3927 中定義的連結本機位址 169.254.0.0/16
、RFC4193 中定義的獨特本機 IPv6 單播位址 fc00::/7
、RFC4291 的第 2.5.6 節中定義的連結本機 IPv6 單播位址 fe80::/10
,以及 IPv4 對應 IPv6 位址,其中對應的 IPv4 位址本身為私人位址。
公開 IP 位址空間包含所有未提及的其他位址。
本地 IP 位址的私密程度高於私人 IP 位址,而私人 IP 位址的私密程度高於公開 IP 位址。
如需瞭解詳情,請參閱「私人網路的 CORS (RFC1918):歡迎提供意見回饋」。
預檢要求
背景
預檢要求是 跨來源資源共享 (CORS) 標準引進的機制,可在向目標網站傳送可能產生副作用的 HTTP 要求前,先向該網站要求權限。這可確保目標伺服器瞭解 CORS 通訊協定,並大幅降低 CSRF 攻擊的風險。
權限要求會以 OPTIONS
HTTP 要求的形式傳送,並附上特定 CORS 要求標頭,說明即將傳送的 HTTP 要求。回應必須附帶特定的 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 問題面板會顯示警告。
您也可以在網路面板中查看及診斷受影響的預檢要求:
如果您的要求會在沒有私人網路存取權規則的情況下觸發一般 CORS 預檢,網路面板中可能會顯示兩次預檢,且第一個預檢一律會顯示為失敗。這是已知錯誤,您可以放心忽略。
如要查看強制執行預先檢查成功的結果,請從 Chrome 98 開始傳遞下列命令列引數:
--enable-features=PrivateNetworkAccessRespectPreflightResults
任何失敗的預先檢查要求都會導致擷取失敗。這樣一來,您就可以測試網站是否能在第二階段的推出計畫後正常運作。您可以使用上述的開發人員工具面板,以與警告相同的方式診斷錯誤。
網站受到影響時的處理方式
這項異動在 Chrome 104 推出時,不會導致任何網站發生問題。不過,我們強烈建議您更新受影響的要求路徑,確保網站能正常運作。
您可以採用下列兩種解決方案:
- 在伺服器端處理預檢要求
- 透過企業政策停用 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-Origin
和 Access-Control-Allow-Private-Network: true
,以及其他必要的標頭。
如需具體情況,請參閱範例。
使用企業政策停用私人網路存取檢查
如果您對使用者有管理控制權,可以使用下列任一政策停用私人網路存取權檢查:
如需更多資訊,請參閱「瞭解 Chrome 政策管理」。
提供意見
如果你在私人網路中代管網站,並預期會收到來自公開網路的要求,Chrome 團隊很樂意聽取你的意見和使用情境。請前往 crbug.com 向 Chromium 回報問題,並將元件設為 Blink>SecurityFeature>CORS>PrivateNetworkAccess
。
後續步驟
接下來,Chrome 將擴大私人網路存取權檢查,涵蓋網頁工作站:專用工作站、共用工作站和服務工作站。我們暫時預計在 Chrome 107 開始顯示警告。
接著,Chrome 會將私人網路存取權檢查擴大至涵蓋導覽,包括 iframe 和彈出式視窗。我們暫時預計在 Chrome 108 開始顯示警告。
無論是哪種情況,我們都會謹慎地以類似的階段性方式推出,讓網頁開發人員有時間調整並評估相容性風險。
特別銘謝
封面相片來源:Mark Olsen 在 Unsplash 網站上提供。