拋出問題
你是否遇到過這樣的問題:以前一個運行得好好的系統,突然在某個時刻(2021年9月21日之后)用戶反饋說用不了了。如果用戶允許你F12進行網絡交互或者控制臺輸出查看時,你會發現這樣的錯誤:
Access
to XMLHttpRequest at 'http://[some_url]' from origin
'http://[some_url]' has been blocked by CORS policy: The request client
is not a secure context and the resource is in more-private address
space 'private'.
然后請求就中斷了,后續的邏輯自然也就沒辦法進行了。乍一看是跨域策略(CORS policy)的問題,趕緊去看看接口的Response Header與跨域相關的配置:
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With, Content-Range, Content-Type
Access-Control-Expose-Headers: Range
和跨域相關的配置也都返回了(要不然以前的系統也不能正常地運行),怎么突然就報錯了呢?如果你遇到了相同的疑問,那么這篇文章就繼續讀下去吧。
復現問題
首先,你操作的業務系統,其域名一定指向的是一個公網IP地址。這里我們假設名為"out.com";
其次,在上述業務系統中調用了另外一個系統的接口,該子系統域名指向的是一個內網IP(無論A類B類還是C類子網)地址(localhost, 127.*.*.*, [::1]除外)。這里我們假設名為“in.com”。
最后,一定是上述兩個系統都采用http協議進行訪問。
舉個例子*:
ping out.com
來自 110.242.68.66 的回復: 字節=32 時間=12ms TTL=48
ping in.com
來自 10.29.10.136 的回復: 字節=32 時間=12ms TTL=48
操作頁面:http://out.com/article/process,在該頁面中有如下JS:
$.ajax({url:"http://in.com/api/auditors", method:"GET", success:function(ret) {}})
那么此時就會復現文章開頭描述的問題。
*注:以上數據經過脫敏處理,所涉及域名和IP地址并非真實數據,僅供內容闡述之用。
問題原因
為什么升級到Chrome 94開始就有問題了呢?在這一版中,它禁止了公共非安全上下文(廣義上說,不通過 HTTPS 或來自私有 IP 地址的網站)向私有網絡發出請求。聽起來很難理解。讓我們抽出這句話的關鍵詞:公共上下文 / 請求 / 私有網絡。
這里不得不聊一下現在的網絡應用背景。越來越多的家庭出現了嵌入式設備。而這些設備的安全性普遍都不是很高。僅僅提供一個簡單的http配置界面給用戶。如果訪問了一個外網別有用心的網頁,里面被嵌入了一個內網的ajax請求,那么這些家庭中的嵌入式設備就很容易遭到攻擊。下面是我總結的一張表格,含義是外網資源采用不同的協議訪問內網資源時的組合情況。
外網訪問內網 | http | https |
http | Chorme 94禁止 | Chorme 94禁止 |
https | 安全內容加載不安全內容,禁止 | 取跨域策略 |
這里可以給大家舉個例子。部分型號的TP-Link路由器,為了方便用戶進行配置,只要連接上(通過有線或者無線),瀏覽器輸入:tplogin.cn就可以自動打開管理界面(域名自動解析到默認網關)。在Chrome 94之前,當用戶打開了一個“精心設計”的http頁面,內部編寫了一套針對tplogin.cn的攻擊JS。那么處于內網的路由器就有被侵入的風險。
其實由此可以聯想到現在的智能手機,在iOS中,如果應用需要網絡權限,用戶可以選擇蜂窩和無線網絡,而無線網絡又可以選擇是否允許訪問本地網絡。此功能與Chrome本次的跨域策略升級其實是基于同樣的考量。
解決方法
方案一:同時升級外部系統和內部系統,都采用https協議訪問;
方案二:如果你有權限控制外部系統,讓外部系統在公司內網中也解析為內網地址。
如果你不得不采用http方式訪問(例如:沒有對應的https證書),那么用戶可以在瀏覽器中禁用掉這一策略。在chrome中打開此地址:
chrome://flags/#block-insecure-private-network-requests
將Block insecure private network requests配置禁用掉(Disable)。但是一定要注意,修改了配置后必須點擊Chrome此時在右下角出現的“重啟”(Restart)按鈕才能生效。自己主動關閉瀏覽器全部頁面再打開是不會觸發Chrome更新配置的。
參考文獻
[1]Titouan Rigoudy,Private Network Access update: Introducing a deprecation trial
[EB/OL].https://developer.chrome.com/blog/private-network-access-update/,2022-02-10.