為了避免內存攻擊,美國國家安全局提倡rust、c#、go、java、ruby 和 swift,但將 c 和 c++ 置於一邊

為了避免內存攻擊,美國國家安全局提倡rust、c#、go、java、ruby 和 swift,但將 c 和 c++ 置於一邊

對於許多開發人員來說,這可能意味著轉向 c#、go、java、ruby、rust 和 swift。

最后更新 2022/11/16 上午7:31
沙漠尽头的狼
预计阅读 17 分钟
分类
分享
标签
.NET C# Java Go 安全

先丢出美国国家安全局的一篇文章:NSA Releases Guidance on How to Protect Against Software Memory Safety Issues

本文翻譯自兩篇文章,第一篇是對美國國家安全局在“軟體內存安全”網絡安全信息表的解讀,第二篇是普及什麼是內存安全,為什麼它很重要?

第一篇 為了避免內存攻擊,美國國家安全局提倡rust、c#、go、java、ruby 和 swift,但將 c 和 c++ 置於一邊

本文來自翻譯(谷歌翻譯加持)。

原文作者: liam tung

原文標題:nsa to developers: think about switching from c and c++ to a memory safe programming language

原文連結:https://www.zdnet.com/article/nsa-to-developers-think-about-switching-from-c-and-cpp-to-a-memory-safe-programming-language/

Image: Getty Images/iStockphoto

對於許多開發人員來說,這可能意味著轉向 c#、go、java、ruby、rust 和 swift。

美國國家安全局 (nsa) 敦促開發人員轉向內存安全語言--例如 c#、go、java、ruby、rust 和 swift--以保護他們的代碼免受遠程代碼執行或其他黑客攻擊。

在上面提到的語言中,java 是企業和 android 應用程式開發中使用最廣泛的語言,而 swift 是前 10 名語言,部分歸功於 ios 應用程式開發。在系統編程中,人們越來越關注 rust 作為 c 和 c++ 的替代品。

“美國國家安全局建議組織考慮在可能的情況下從提供很少或不提供內在內存保護的程式語言(例如 c/c++)到內存安全語言的戰略轉變。內存安全語言的一些示例包括 c#、go、java、ruby和swift。”美國國家安全局說。

该间谍机构援引谷歌和微软最近的研究表明,他们 70% 的安全问题(分别在 Chrome和 Windows 中)与内存相关,其中许多是使用 C 和 C++ 的结果,它们更容易出现基于内存的漏洞.

另外: 网络安全、云和编码:为什么这三项技能将在 2023 年引领需求

美国国家安全局在“软件内存安全”网络安全信息表中指出:“恶意网络行为者可以利用这些漏洞进行远程代码执行或其他不利影响,这通常会危及设备并成为大规模网络入侵的第一步。 ”

“c 和 c++ 等常用語言在內存管理方面提供了很大的自由度和靈活性,同時嚴重依賴程式設計師對內存引用執行所需的檢查。”

因此,該機構建議儘可能使用內存安全語言,無論是用於應用程式開發還是系統編程。

“nsa 建議儘可能使用內存安全語言,”它指出。

虽然大多数信息安全专家都熟悉这场关于内存安全语言的争论,但也许并非所有开发人员都熟悉。不过,考虑到这是一个存在了几十年的问题,也许他们应该这样做,正如 Java 的创建者 James Gosling 最近在一次关于如何以及为什么创建 Java 的讨论中指出的那样。

如果有的話,nsa 文件為開發人員提供了一個清晰、通俗易懂的語言解釋,說明了轉向內存安全語言背後的技術原因。在內存安全方面討論最多的語言可能是 rust,它是 c 和 c++ 的“替代品”的主要候選語言。

继 Android 开源项目之后,Linux 内核 最近将 Rust 作为 C 的第二语言引入。这些项目不会替换旧的 C/C++ 代码,但会更喜欢 Rust 作为新代码。此外,Microsoft Azure CTO Mark Russinovich 最近呼吁所有开发人员在所有新项目中使用 Rust 而不是 C 和 C++

“通過利用這些類型的內存問題,不受軟體使用正常預期約束的惡意行為者可能會發現他們可以向程式輸入不尋常的輸入,導致以意想不到的方式訪問、寫入、分配或釋放內存,”美國國家安全局解釋道。

但是——正如专家在关于 Rust 和 C/C++ 的辩论中指出的那样 ——美国国家安全局警告说,简单地使用内存安全语言并不能默认排除将内存错误引入软件。此外,语言通常允许不是用内存安全语言编写的库。

“即使使用內存安全語言,內存管理也不完全是內存安全的。大多數內存安全語言都認識到軟體有時需要執行不安全的內存管理功能才能完成某些任務。因此,可以使用被認為是非內存安全並允許程式設計師執行可能不安全的內存管理任務,”美國國家安全局說。

“一些語言要求任何內存不安全的東西都被顯式注釋,以使程式設計師和程式的任何審閱者意識到它是不安全的。內存安全語言也可以使用以非內存安全語言編寫的庫,因此可以包含不安全的內存功能.儘管這些包含內存不安全機制的方法顛覆了固有的內存安全性,但它們有助於定位可能存在內存問題的位置,從而允許對這些代碼部分進行額外的審查。

另外: 网络安全:这些是 2023 年需要担心的新事物

NSA 指出,某些内存安全语言可能会以性能成本为代价,这需要开发人员学习一门新语言。它还指出开发人员可以采取一些措施来强化非内存安全语言。例如, Google 的 Chrome 团队正在探索多种强化 C++ 的方法,但这些方法也会带来性能开销。在可预见的未来,C++ 将保留在 Chrome 的代码库中。

nsa 建議進行靜態和動態應用程式安全測試以發現內存問題。它還建議探索內存強化方法,例如 control flow guard (cfg),這將限制代碼的執行位置。同樣,建議使用地址空間布局隨機化 (aslr) 和數據執行保護 (dep)。

第二篇 什麼是內存安全,為什麼它很重要?

本文來自翻譯(谷歌翻譯加持)。

出處:https://www.memorysafety.org

原文標題:what is memory safety and why does it matter?

原文連結:https://www.memorysafety.org/docs/memory-safety/

內存安全是一些程式語言的一個屬性,它可以防止程式設計師引入與內存使用方式相關的某些類型的錯誤。由於內存安全漏洞通常是安全問題,因此內存安全語言比非內存安全語言更安全。

內存安全語言包括 rust、go、c#、java、swift、python 和 javascript。內存不安全的語言包括 c、c++ 和彙編語言。

內存安全漏洞的類型

為了開始理解內存安全漏洞,我們將考慮一個為許多用戶維護待辦事項列表的應用程式示例。我們將了解幾種最常見的內存安全錯誤類型,它們可能發生在內存不安全的程式中。

越界讀寫

如果我們有一個包含十項的待辦事項列表,而我們要求第十一項,會發生什麼?顯然我們應該收到某種錯誤。如果我們要求否定的第一項,我們也應該得到一個錯誤。

在這些情況下,內存不安全的語言可能允許程式設計師讀取列表的有效內容之前或之後恰好存在的任何內存內容。這稱為越界讀取。列表第一項之前的內存可能是其他人列表的最後一項。列表最後一項之後的內存可能是其他人列表的第一項。訪問此內存將是一個嚴重的安全漏洞!程式設計師可以通過仔細檢查他們要求的項目的索引與列表的長度來防止越界讀取,但是程式設計師會犯錯誤。最好使用一種內存安全語言,默認情況下可以保護您和您的用戶免受此類錯誤的侵害。

在內存安全語言中,我們會在編譯時出錯或在運行時崩潰。程式崩潰看似嚴重,但總比讓用戶竊取彼此的數據要好!

一個密切相關的漏洞是越界寫入。在這種情況下,假設我們試圖更改待辦事項列表中的第十一項或否定的第一項。現在我們正在改變別人的待辦事項清單!

釋放後使用

想像一下,我們刪除了一個待辦事項列表,然後請求該列表的第一項。顯然我們應該收到一個錯誤,因為我們不應該能夠從已刪除的列表中獲取項目。內存不安全的語言允許程式獲取他們已經完成的內存,現在可以將其用於其他用途。內存中的位置現在可能包含其他人的待辦事項列表!這稱為釋放後使用漏洞。

內存安全漏洞有多普遍?

极其。最近的一项研究发现,iOS 和 macOS 中 60-70% 的漏洞是内存安全漏洞。Microsoft 估计,在过去十年中,其产品中的所有漏洞中有 70% 是内存安全问题。谷歌估计 90% 的 Android 漏洞都是内存安全问题。对被发现广泛被利用的 0-day 的分析发现,超过 80% 的被利用漏洞是内存安全问题1。

2003 年的Slammer 蠕虫(这是一种专门衡量软件漏洞的方法,它不包括诸如凭据网络钓鱼之类的非常普遍的事情。)是缓冲区溢出(越界写入)。WannaCry(越界写入)也是如此。针对 iPhone的Trident 漏洞利用了三个不同的内存安全漏洞(两个释放后使用和一个越界读取)。HeartBleed是内存安全问题(越界读取)。Android 上的Stagefright也是如此(越界写入)。glibc 中的Ghost漏洞?你打赌(越界写)。

由于 C 和 C++ 不是内存安全的,因此这些漏洞以及利用其他漏洞成为可能。编写大量 C 和 C++ 的组织不可避免地会产生大量漏洞,这些漏洞可直接归因于缺乏内存安全性。这些弱点被利用,给医院持不同政见者卫生政策专家带来危险。使用 C 和 C++对社会不利,对您的声誉不利,对您的客户不利。

與內存不安全的語言相關的還有哪些其他問題?

內存不安全的語言也會對穩定性、開發人員生產力和應用程式性能產生負面影響。

由於內存不安全的語言往往會出現更多錯誤和崩潰,因此會極大地影響應用程式的穩定性。即使崩潰不是安全敏感的,它們對用戶來說仍然是非常糟糕的體驗。

更糟糕的是,開發人員很難追蹤到這些錯誤。內存損壞通常會導致崩潰發生在距離錯誤實際位置很遠的地方。當涉及多線程時,線程運行時間的微小差異可能會觸發其他錯誤,從而導致更難重現錯誤。結果是開發人員通常需要盯著崩潰報告看幾個小時才能確定內存損壞錯誤的原因。這些錯誤可能幾個月都沒有修復,開發人員完全相信存在錯誤,但不知道如何在發現其原因和修複方面取得進展。

最後,還有性能。在過去的幾十年裡,人們可以指望 cpu 每一兩年都變得更快。這已不再是這種情況。相反,cpu 現在帶有更多內核。為了利用額外的內核,開發人員需要編寫多線程代碼。

不幸的是,多線程加劇了與缺乏內存安全相關的問題,因此,在 c 和 c++ 中利用多核 cpu 的努力通常是棘手的。例如--在最終(成功)用多線程 rust 重寫系統之前,mozilla 多次嘗試將多線程引入 firefox 的 c++ css 子系統,但均以失敗告終。

正確的前進道路是什麼?

使用內存安全語言!有很多很棒的可供選擇。編寫作業系統內核或 web 瀏覽器?考慮rust!為 ios 和 macos 構建?swift可以勝任。網絡伺服器?go 是個不錯的選擇。這些只是幾個例子,還有許多其他優秀的內存安全語言可供選擇(以及許多其他精彩的用例配對!)。

更改您的組織使用的程式語言並非輕而易舉。這意味著改變你在招聘時尋找的技能,這意味著對你的員工進行再培訓,這意味著重寫大量代碼。儘管如此,我們相信從長遠來看這是必需的,因此我們想說明為什麼採用新程式語言的替代方案沒有成功。

如果我們理所當然地認為使用不安全的語言會產生一些漏洞,那麼我們想問的問題是:我們是否可以採取一些技術來降低這種風險,而不用強迫自己完全改變程式語言?答案是肯定的。並非所有用不安全語言編寫的項目都同樣不安全和不可靠。

一些可以降低使用不安全語言風險的做法是:

  • 使用一些现代 C++ 惯用语可以帮助生成更安全可靠的代码
  • 使用fuzzerssanitizers帮助在将错误投入生产之前找到它们
  • 使用漏洞利用緩解措施來幫助增加利用漏洞的難度
  • 權限分離,即使漏洞被利用,爆炸半徑也更小

這些做法有意義地降低了使用不安全語言的風險,如果我們未能說服您更換語言,而您打算繼續編寫 c 和 c++,那麼採用這些做法勢在必行。不幸的是,它們也嚴重不足。

浏览器和操作系统开发人员是开发现代 C++ 惯用语、fuzzerssanitizers、漏洞利用缓解和权限分离技术的最前沿人员——正是我们在开始时通过有关内存安全问题普遍性的统计数据强调的群体。尽管这些团队在这些技术上进行了投资,但他们使用不安全的语言却拖累了他们。在大型黑客大赛pwn2own上,2019年这些产品被利用的漏洞中有一半以上是由于缺乏内存安全,除了一个例外,每一次成功的攻击都至少利用了一个内存安全漏洞。

放棄 c 和 c++ 真的可行嗎?

希望到現在為止,我們已經讓您相信,像 c 和 c++ 這樣的不安全語言是我們產品中大量不安全的根本原因,並且儘管您可以採取一些措施來降低風險,但您無法接近消除它。所有這些可能仍然讓你覺得改變你使用的程式語言,產生數百萬行代碼,是一個壓倒性的巨大任務。通過將其分解為可管理的部分,我們可以開始取得進展--我們的目標不是大爆炸式地重寫世界,而是在降低風險方面取得進展。

首先是全新的項目。對於這些,您可以選擇簡單地使用內存安全語言。這些項目的風險最低,因為您不需要從重寫任何代碼開始,儘管像這樣的項目通常確實需要改進測試或部署基礎設施以支持新的程式語言。這是 chromeos 的 crosvm(作業系統的全新組件)所採用的方法。

如果您没有新项目,下一个寻找机会使用内存安全语言的地方是现有项目的新组件。一些内存安全语言对与 C 和 C++ 代码库(例如 Rust 和 Swift)的互操作提供了一流的支持。这需要稍高的初始投资,因为它需要集成到构建系统中,以及使用新语言为需要跨越两种语言之间的边界传递的对象和数据构建抽象。当WebAuthn作为 Firefox 的一个新组件实现时,以及一个支持在 Rust 中编写 Linux 内核模块的项目,就成功地使用了这种策略。

前兩種方法的共同點是它們都處理新代碼。這具有與現有代碼定義明確的交互點的優勢,並且無需重寫任何內容即可開始工作。它還為您提供了止血的機會:沒有使用不安全語言的新組件,我們將逐步處理現有代碼。對於沒有任何自然的新組件來開始使用內存安全語言的項目,採用更具挑戰性。

在這種情況下,您需要尋找一些現有組件以將不安全語言重寫為安全語言。最好是您選擇的組件是您已經考慮重寫的組件:可能是為了性能、安全性,或者是因為代碼太難維護。你應該嘗試為你的第一次內存安全重寫選擇範圍儘可能小的東西,以幫助項目成功並儘快發布;這有助於將重寫中固有的風險降至最低。stylo,用 rust 重寫了 firefox 的 css 引擎,是這種方法的一個成功例子。

無論哪種方法最適合您的組織,都需要牢記一些事項以最大程度地提高成功的機會。首先是確保你有內部支持者和高級工程師,他們可以使用對許多團隊成員來說都是新的語言提供代碼審查和指導。這樣做的自然延伸是確保將使用新語言工作的工程師有可用的資源,如書籍、培訓或內部指南。最後,您需要確保新語言擁有與舊語言相同的共享基礎設施,例如構建系統、測試、部署、崩潰報告和其他集成。

結論

採用一種新的程式語言並開始遷移到它的過程並不是一件容易的事。它需要整個組織的規劃、資源配置和最終投資。如果我們不必考慮這些事情,生活會容易得多。不幸的是,對數據的審查清楚地表明,我們根本不能考慮繼續為安全敏感項目使用不安全的語言。

數據一次又一次地證明,當項目使用 c 和 c++ 等不安全語言時,它們就會受到大量安全漏洞的困擾。無論工程師多麼有才華,在權限減少和利用緩解方面的投資有多大,使用內存不安全的語言只會導致太多錯誤。這些錯誤大大降低了安全性、穩定性和生產力。

幸運的是,我們不需要滿足於現狀。在過去的幾年中,出現了 c 和 c++ 的絕佳替代品,例如 rust、swift 和 go 等。這意味著我們不必在未來的許多年裡將內存損壞漏洞作為一個信天翁掛在脖子上,只要我們選擇不這樣做。我們期待有一天,選擇使用不安全的語言被認為是疏忽大意,因為沒有多因素身份驗證或沒有加密傳輸中的數據。

感謝亞歷克斯蓋納

经许可,此解释基于 Alex Gaynor 的博客文章工程副总裁的内存不安全简介

本文總結

希望大家能從這兩篇譯文中得到些什麼。

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2025/8/13

推薦一款高性能狀態機管理解決方案

在實際軟體開發中,尤其是工業軟體,每一款設備都有複雜的狀態以及狀態之間的切換的功能需求,在這種情況下,如何管理狀態以及狀態之間切換,和對應狀態下的功能控制,成為非常重要的一個問題。

继续阅读