Google也要放棄C/C++?Chrome 代碼庫中70%的安全漏洞是內存問題

Google 工程師表示:目前 Chrome 代碼庫中所有嚴重的安全漏洞,70% 是內存管理的安全漏洞,其中 50% 的內存漏洞是 use-after-free 漏洞,因爲對內存指針的錯誤管理,給予了攻擊者攻擊 Chrome 內部組件的機會。

近日,Google 工程師統計了 2015 年以來,Chrome 穩定分支中修復級別爲"high" 或"critical" 的 912 個安全錯誤,結果發現約 70% 是內存安全漏洞。

事實上,不只是 Google,內存安全漏洞是很多科技公司都頭疼的問題,微軟工程師也曾公開表示:在過去 12 年中,微軟產品的安全更新中,約有 70% 也是在解決內存安全漏洞。

爲什麼微軟和 Google 的情況如此相似呢?因爲它們代碼庫中使用的主要編程語言是 C 和 C++,由於 C 和 C++ 出現的時間較早,當時網絡攻擊還不是利用相關的威脅模型,大多數早期軟件開發人員也沒有考慮到相關的安全問題,所以 C 和 C++ 允許程序員完全控制管理應用程序的內存指針,出現基本的內存管理錯誤時,也沒有相關的提示或者警告。

Chrome 的內存安全問題如何解決?

據瞭解,自 2019 年 3 月以來,在 130 個級別爲 critical 的 Chrome 漏洞中,有 125 個是與內存相關的。這個數據也表明了,內存管理錯誤仍然是 Google 的一個大問題。

爲了解決內存安全問題,Google 內部提出了一個 The Rule Of 2 原則,即爲了保證安全性,程序員不能破壞兩個以上的條件:

  • 不可靠的輸入:主要來自兩個方面,一是 non-trivial 的語法,例如常用的 and 和 or,二是不安全的來源;
  • 不安全的實現語言:即在編寫程序時選擇了缺乏內存安全性的語言,例如 C、C++、彙編語言等。目前內存安全的語言包括 Go、Rust、Python、Java、JavaScript、Kotlin 和 Swift 等。
  • 高特權:特權最高的程序是計算機固件,引導加載程序、內核、系統管理程序或虛擬機監視器等;其次是操作系統級別的賬戶運行進程;特權較低的進程包括 GPU 進程和網絡進程等。

“沙箱”也是 Google 用來解決安全問題的常用方法,Google 工程師會將數十個流程隔離到自己的沙箱中,並利用剛推出的“Site Isolation”功能,將每個站點的資源也放到沙箱中。同時,考慮到性能問題,Google 採用了沙箱化 Chrome 組件的方法,並在積極探索新的方法。

Google 表示將開發自定義 C++ 庫,與 Chrome 代碼庫配合使用,以便更好地處理與內存相關的錯誤。並且有計劃,在可能的情況下探索使用“內存安全”的編程語言,目前的候選對象包括 Rust、Swift、JavaScript、Kotlin 和 Java。

放棄 C 和 C++ 可行嗎?

無論是 Google 還是微軟,出現內存問題的根源是使用了諸如 C 和 C++ 這類的“不安全”編程語言,那麼放棄 C 和 C++ 可行嗎?

對企業來說,重新選擇一種編程語言不是一件容易的事情,因爲這意味着需要重寫大量的代碼,需要重新培訓員工,需要招聘擁有新技能的員工。所以,放棄 C 和 C++ 不是一件容易的事情。

如果是全新的項目,我們完全可以選擇一個內存安全的編程語言,無需考慮重寫代碼的風險。不過,還是需要改進測試或部署基礎架構來支持新的編程語言。ChromeOS 的 CrosVM 就是採用的這種方法。

如果是現有項目的新組件,我們也可以選擇內存安全的編程,例如 Rust、Swift 等編程語言都可以與 C、C++ 代碼庫互操作。不過,剛開始的投入可能會比較大,因爲需要集成到構建系統中,所以需要使用一種新的語言在兩種語言之間傳遞對象和數據構建抽象。Firefox 的新組件 WebAuthn 就是使用的這種方法。

以上兩種情況的特點都是新代碼與原有代碼有明顯的界限,無需重寫代碼,我們可以在構建新項目或新組件之後,再逐步處理現有代碼。那如果是界限不明顯、無法放棄 C 和 C++ 的情況,我們又該怎麼辦呢?

  • 使用一些現代 C++ 習慣用法來生產更安全可靠的代碼;
  • 使用 fuzzers 和 sanitizers 提前發現錯誤;
  • 使用 exploit mitigations 增加利用漏洞的難度;
  • 特權分離,這樣即使利用了漏洞,受影響的半徑也較小。

相關閱讀:

https://www.chromium.org/Home/chromium-security/memory-safety

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章