從程式語言層級確保記憶體安全,不只美國NSA建議,今年Prossimo專案也在推動
<div class="field field-name-field-image field-type-image field-label-hidden"><div class="field-items"><div class="field-item even"><img src="https://s4.itho.me/sites/default/files/zhu_tu_mei_guo_nsajian_yi_kai_fa_zhe_duo_yong_bao_zhang_ji_yi_ti_an_quan_cheng_shi_yu_yan_960.jpg" width="960" height="420" alt="" /></div></div></div><div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"> <p>在本月10日,美國國家安全局(NSA)公開發表一份軟體開發指南,是針對軟體記憶體安全(Memory Safety)而來,建議開發者應多使用保障記憶體安全的程式語言,如C#、Rust、Go、Java、Ruby、Swift,以這些來取代C與C++,引起軟體開發界的討論。</p> <p>事實上,關於C、C++的資安爭論已持續多年,但隨著記憶體安全問題受到越來越大的重視,開發者輕忽指標、記憶體配置的狀況太過普遍,而願意花心力檢測、有足夠經驗處理這類問題的程式設計者太少,而使得軟體資安漏洞層出不窮。</p> <p>儘管為了降低這方面犯錯的機會,開發界持續宣導C/C++程式設計要重視記憶體管理,有些開發者的確能夠寫出足夠安全的C/C++程式碼,但對大多數程式設計師來說,卻可能並非易事,有些科技業者祭出記憶體安全機制來因應,但多年下來,犯錯比例仍是居高不下,這也使得另一條因應路線被持續探討,也就是多用具記憶體安全特性的程式語言,如此一來,即便是資安意識不足的開發人員,也因為開發環境的局限,而不用擔心記憶體管理的問題,減少犯錯的機會。而且,如今這類軟體開發安全措施的推動態勢,也從一些科技大廠而開始擴及國家政府機構。</p> <h3><strong>多數軟體漏洞可歸咎於記憶體安全性不足</strong></h3> <p>在今年5月,我們看到開源社群、科技大廠與美政府二度商討開源軟體安全對策,會後Linux基金會與開源安全基金會(OpenSSF)發布的開源軟體安全動員計畫白皮書中,替換不具記憶體安全(non-memory-safe)的程式語言,就是十大對策之一,並預計前兩年針對這方面投入經費550萬美元。</p> <p>到了11月,美國NSA也對此公開表態。針對軟體記憶體安全問題,他們建議各組織在可能情況下,對於程式語言的採用,應考慮做出戰略性的轉變,從不具記憶體保護的C/C++,轉而使用具記憶體安全的其他程式語言,例如C#、Go、Java、Ruby與Swift等。</p> <p>在這份公開文件中,NSA首先強調軟體記憶體安全的重要性,指出雖然開發人員經常進行嚴格測試,為軟體中的邏輯準備好應對意外情況,然而,各種可濫用的軟體漏洞,仍經常是基於記憶體問題而成。例如:記憶體緩衝區溢位,以及管理記憶體失當而導致的洩漏問題。</p> <p>最近幾年已有更多這方面的研究,例如,微軟在2019年曾公開提出自我檢討,他們表示,在2006年到2018年間的安全漏洞,有70%源自記憶體的安全問題,Google在2020年也針對自家發展的瀏覽器Chrome提出檢討,當中也存在同樣高比例的記憶體安全漏洞。由於存在規模如此龐大的軟體開發缺失,駭客可利用這些漏洞來執行遠端程式攻擊,作為大舉入侵組織網路的第一步。</p> <p>而在程式語言中,現今應用範圍最大且最常見的C與C++,方便之餘,多年來大家也經常詬病其安全性管制太少,而使得記憶體類型的漏洞總是無法徹底根絕。事實上,這兩種語言在記憶體管理上,提供了很大的自由度與彈性,相對地,用這些語言所開發的應用程式,其安全性將高度依賴開發者的處理方式,例如,是否對記憶體參照執行必要的檢查與驗證。因此,可能只要出現一個簡單的錯誤、疏忽,就會導致記憶體遭濫用的安全漏洞。</p> <p>固然我們可以透過軟體分析工具偵測出許多記憶體管理問題,透過作業系統環境本身內建的機制,也能帶來某些程度的保護,但NSA認為,若能藉由已內建記憶體保護的程式語言來撰寫程式,即可避免或減少絕大多數的記憶體管理問題。</p> <h3><strong>緩衝區溢位、管理不當,均是常見記憶體安全問題</strong></h3> <p>記憶體安全,也就是有關於程式如何管理記憶體的一大類問題。這當中有哪些常見問題?</p> <p>NSA指出,記憶體「緩衝區溢位」(buffer overflow)就是一例,也就是資料的存取意外超出緩衝區邊界(outside the bounds),另一個常見的安全問題則與記憶體分配有關。</p> <p>簡單來說,系統程式在執行時可以分配新的記憶體位置,然後在不需要記憶體時,將其取消分配,此舉稱為釋放記憶體,但如果開發者不小心這麼做,新的記憶體可能會在程式執行過程中被重複分配,因此,記憶體並非總是在不再需要時被釋放,進而出現記憶體洩漏(memory leak)的問題,最終甚至導致可用的記憶體資源被使用殆盡。</p> <p>此外,也有因邏輯錯誤而出現記憶體存取不安全的狀況。因為這樣的問題,程式可能試圖使用已經被釋放的記憶體,甚至重複釋放原本已被釋放的記憶體。例如,當程式語言允許使用尚未初始化的變數時,就會出現另一個問題,導致該變數使用之前在記憶體中該位置設置的值。</p> <p>另一個值得注意的問題,則是條件競爭(Race condition)。例如,當程式存取相同資料,此時若出現兩個操作順序,可能會因此影響程式的結果,而發生這個問題。NSA強調,所有這些記憶體問題都是相當常見的現象。</p> <p>而且,記憶體管理問題衍生安全漏洞只是其中一種類型的狀況,就算是不會遭到濫用的記憶體,也可能因為一些疏失而造成錯誤的程式結果,例如,降低執行效能或軟體本身無法執行。</p> <p>針對上述種種軟體記憶體安全的問題,NSA指出,採用能夠自動管理記憶體的程式語言,像是C#、Rust、Go、Java、Ruby、Swift等,可協助避免開發者陷入某些類型的記憶體問題,以預防無意採用錯誤的記憶體管理方式。</p> <p>但NSA也提醒,就算是使用這些內建記憶體保護的程式語言,也並非毫無風險,因為軟體有時仍需要執行不安全的記憶體管理功能,才能完成任務,而且,各種程式語言對記憶體的安全保護程度不一,因此不能單靠更換程式語言而確保軟體安全。</p> <p>另一方面,對於無法立即轉向採用內建記憶體安全的程式語言的開發者,NSA建議,應透過安全測試來強化應用程式的安全性,包括進行靜態(SAST)與動態(DAST)的安全測試,而且最好是執行多個SAST及DAST工具,以提高找出記憶體問題的機率,確保應用程式的安全。儘管這可能會增加大量的工作負擔,卻可以帶來更安全的程式碼。</p> <p>總之,NSA鼓勵組織儘可能採取多管齊下的方式,來強化記憶體管理的安全性。除了採用記憶體安全程式語言,還可同時輔以編譯器選項、工具分析及作業系統配置,以減少記憶體漏洞,提高駭客的攻擊門檻。</p> <h3><strong>今年出現Prossimo專案,開始推動安全程式語言的廣泛採用</strong></h3> <p>對於NSA的這項建議,根據IT新聞媒體The Register的<a href="https://www.theregister.com/2022/11/11/nsa_urges_orgs_to_use/">報導</a>,Acronis資安長Kevin Reed認為,NSA正在做正確的事情,但他懷疑這是否會有立竿見影的效果,因為多年來使用C/C++撰寫的程式碼數量龐大,即便明天就開始改用Rust與Go,也需要幾十年才能清理這個爛攤子。</p> <p>而且,真的能夠如此順利推動嗎?微軟Azure技術長Mark Russinovich在今年9月就曾針對這樣的議題,於社群媒體推特發表了看法。他指出,在安全性與可靠性考量下,現在該停用C/C++開發任何新專案,並建議改用Rust。但在此則貼文回應中,有相當多開發者持反對意見,畢竟C與C++仍是熱門程式語言。</p> <p>但無論如何,記憶體安全問題已不容忽視。對照MITRE公布的2022年25大常見CWE通用弱點列表名單,我們可以發現,記憶體越界寫入(Out of Bounds Writes),記憶體越界讀取(Out of Bounds Reads),以及使用已釋放的記憶體(Use after Free),都在前七名內,尤其是記憶體越界寫入,持續居於第一嚴重的地位,而這樣居高不下的排名,也呼應多數軟體漏洞可直接歸因於缺乏記憶體安全性的推論。</p> <p>而在今年5月Linux基金會與OpenSSF發布的「開源軟體安全動員計畫」白皮書中,其實已經針對此問題提出對策,此計畫的主要目標,是減少記憶體安全性漏洞的數量。</p> <p>首先,他們希望,在網際網路上最關鍵的軟體,能夠遠離C/C++等不安全的程式語言,並強調會優先升級對安全最敏感的元件,其次,系統級程式碼的工具需要受到更大的關注,因為這些是生態系統中最普遍與最脆弱的軟體,也最有可能是以不安全的系統程式語言所寫成,而產生了資安漏洞。</p> <p>同時,這項戰略的執行,將透過非營利組織網際網路安全小組(ISRG)的Prossimo專案來推動。目前這項計畫鎖定那些面向?例如,針對用C語言撰寫的Linux Kernel,如今已有Rust for Linux專案啟動;針對用C語言撰寫的OpenSSL,在替代方案上,也有一套名為Rustls的開放軟體專案正在發展。其餘面向還包括:網路時間協定NTP、Apache httpd的mod_tls模組、Trust-DNS、網路傳輸程式curl,Prossimo專案將針對相關工具進行投資,目的是讓建構更安全軟體變得簡單。</p> <p>而在這些消息中,我們可以發現支持採用Rust的聲浪最大,而且,許多大型企業與開源專案也都嘗試用Rust來撰寫,像是Google的Android與Chrome、Amazon的虛擬化技術Firecracker等。</p> <p>無論如何,因應軟體開發造成的記憶體安全性問題,已不只是口頭呼籲,而是有所行動,再加入美國NSA難得表態力挺使用安全程式語言,使得這項一再受到討論與思考的問題,出現了更多大幅改善的機會。文⊙羅正漢、陳曉莉</p> <p><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E5%9C%962%EF%BC%89%E7%BE%8E%E5%9C%8BNSA%E5%BB%BA%E8%AD%B0%E9%96%8B%E7%99%BC%E8%80%85%E5%A4%9A%E7%94%A8%E4%BF%9D%E9%9A%9C%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80.jpg" style="width: 600px;" /></p> <p><strong>根據Wikipedia上對於<span class="mw-page-title-main">Stack buffer overflow</span>的說明,當中也特別以圖像化方式表達緩衝區溢位的攻擊利用方式。</strong></p> <p><strong><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E5%9C%962%EF%BC%89MITRE%E5%85%AC%E5%B8%83%E7%9A%842022%E5%B9%B425%E5%A4%A7%E5%B8%B8%E8%A6%8BCWE%E9%80%9A%E7%94%A8%E5%BC%B1%E9%BB%9E%E5%88%97%E8%A1%A8%E5%90%8D%E5%96%AE.jpg" style="width: 600px;" /></strong></p> <p><b>根據</b><strong>MITRE在今年8月3日<a href="http://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html">公布的2022年25大常見CWE通用弱點列表名單</a>(2022 CWE Top 25 Most Dangerous Software Weaknesses),我們可以看出在漏洞根因中,記憶體越界寫入(Out of Bounds Writes)居於第一,且指標分數高達64.20,記憶體越界讀取(Out of Bounds Reads)居第五,使用已釋放的記憶體(Use after Free)居第七。</strong></p> <p><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E5%9C%964%EF%BC%89%E7%BE%8E%E5%9C%8BNSA%E5%BB%BA%E8%AD%B0%E9%96%8B%E7%99%BC%E8%80%85%E5%A4%9A%E7%94%A8%E4%BF%9D%E9%9A%9C%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80_201902-07%E5%BE%AE%E8%BB%9FBlueHat%20IL.jpg" style="width: 600px;" /></p> <p><strong><span style="color:#B22222;">2019年2月7日</span> 微軟MSRC研究人員Matt Miller在<a href="https://github.com/Microsoft/MSRC-Security-Research/blob/master/presentations/2019_02_BlueHatIL/2019_01%20-%20BlueHatIL%20-%20Trends%2C%20challenge%2C%20and%20shifts%20in%20software%20vulnerability%20mitigation.pdf">BlueHat IL</a>資安會議的演講中表示,從2006年到2018年間,每一年發布的漏洞修補更新,有70%是與記憶體安全問題有關。</strong></p> <p><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E5%9C%965%EF%BC%89%E5%BE%9E%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80%E5%B1%A4%E7%B4%9A%E7%A2%BA%E4%BF%9D%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8_2020-05-16_Google.jpg" style="width: 600px;" /></p> <p><strong><span style="color:#B22222;">2020年5月16日</span> Chromium專案研究人員<a href="https://www.ithome.com.tw/news/137826">指出</a>,此項軟體有超過70%的嚴重安全漏洞來自記憶體安全漏洞,也就是因C/C++指標操作錯誤所造成,其中一半的錯誤是釋放後使用(Use-After-Free)的問題。</strong></p> <p><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E5%9C%966%EF%BC%89%E5%BE%9E%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80%E5%B1%A4%E7%B4%9A%E7%A2%BA%E4%BF%9D%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8_2022-05-13_Replacement%20Non-Memory-safe.jpg" style="width: 600px;" /></p> <p><strong><span style="color:#B22222;">2022年5月13日</span> 為了解決開源軟體安全問題,開源社群、科技大廠與美政府二度商討對策,會後發布「開源軟體安全動員計畫」白皮書,<a href="https://www.ithome.com.tw/news/151045">針對10大關鍵挑戰提出投資戰略</a>,當中1項就是聚焦於替換不具記憶體安全的程式語言。</strong></p> <p><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E5%9C%968%EF%BC%89%E5%BE%9E%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80%E5%B1%A4%E7%B4%9A%E7%A2%BA%E4%BF%9D%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8_%E5%BE%AE%E8%BB%9FMark%20Russinovich.jpg" style="width: 600px;" /></p> <p><strong><span style="color:#B22222;">2022年9月20日</span> 微軟Azure技術長Mark Russinovich在推特發文<a href="https://www.ithome.com.tw/news/153156">表示</a>,在安全性與可靠性考量下,現在應停用C/C++開發新專案,建議改用Rust。但許多開發者表示反對,因為C與C++畢竟是熱門程式語言。</strong></p> <p><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E5%9C%969%EF%BC%89%E5%BE%9E%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80%E5%B1%A4%E7%B4%9A%E7%A2%BA%E4%BF%9D%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8_Tor.jpg" style="width: 600px;" /></p> <p><strong><span style="color:#B22222;">2022年10月4日</span> 以洋蔥路由聞名的開源軟體專案Tor,釋出以Rust重新實作的版本時<a href="https://www.ithome.com.tw/news/152886">表示</a>,在2001年用C語言是合理選擇,但他們發現安全使用C語言需付出許多心力,程式碼分析與安全性改進也變得越來越困難。</strong></p> <p><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E4%B8%BB%E5%9C%963%EF%BC%89%E7%BE%8E%E5%9C%8BNSA%E5%BB%BA%E8%AD%B0%E9%96%8B%E7%99%BC%E8%80%85%E5%A4%9A%E7%94%A8%E4%BF%9D%E9%9A%9C%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80.jpg" style="width: 600px;" /></p> <p><strong><span style="color:#B22222;">2022年11月10日</span> 美國NSA公開<a href="https://www.ithome.com.tw/news/154180">發表防範軟體記憶體安全問題的軟體開發指南</a>,建議開發人員使用保障記憶體安全的程式語言,例如:C#、Rust、Go、Java、Ruby或Swift,以取代C與C++。</strong></p> <p><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E5%9C%961%EF%BC%89%E7%BE%8E%E5%9C%8BNSA%E5%BB%BA%E8%AD%B0%E9%96%8B%E7%99%BC%E8%80%85%E5%A4%9A%E7%94%A8%E4%BF%9D%E9%9A%9C%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80.jpg" style="width: 600px;" /></p> <p><img alt="" src="https://s4.itho.me/sites/default/files/images/%EF%BC%88%E5%9C%967%EF%BC%89%E5%BE%9E%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80%E5%B1%A4%E7%B4%9A%E7%A2%BA%E4%BF%9D%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8_Prossimo.jpg" style="width: 600px;" /></p> <p><strong>因應記憶體安全(Memory Safety)問題,不再只是呼籲口號,根據「開源軟體安全動員計畫」白皮書指出,已有非營利組織網際網路安全小組(ISRG)的Prossimo專案負責推動相關工作,當中建議使用Rust、Go、C#、java、Swift、Python與JavaScript等語言,來取代使用不具記憶體安全的C、C++與assembly。該專案網站:<a href="https://www.memorysafety.org/">https://www.memorysafety.org/</a></strong></p> </div></div></div><div class="field field-name-field-tags field-type-taxonomy-term-reference field-label-above"><div class="field-label">Tags: </div><div class="field-items"><div class="field-item even"><a href="/tags/memory-safety">Memory Safety</a></div><div class="field-item odd"><a href="/tags/%E8%BB%9F%E9%AB%94%E8%A8%98%E6%86%B6%E9%AB%94%E5%AE%89%E5%85%A8">軟體記憶體安全</a></div><div class="field-item even"><a href="/tags/c-1">C</a></div><div class="field-item odd"><a href="/tags/c">C++</a></div><div class="field-item even"><a href="/tags/rust">Rust</a></div><div class="field-item odd"><a href="/tags/non-memory-safe">non-memory-safe</a></div><div class="field-item even"><a href="/tags/%E7%B7%A9%E8%A1%9D%E5%8D%80%E6%BA%A2%E4%BD%8D">緩衝區溢位</a></div><div class="field-item odd"><a href="/tags/%E8%A8%98%E6%86%B6%E9%AB%94%E6%B4%A9%E6%BC%8F">記憶體洩漏</a></div><div class="field-item even"><a href="/tags/%E8%A8%98%E6%86%B6%E9%AB%94%E8%B6%8A%E7%95%8C%E5%AF%AB%E5%85%A5">記憶體越界寫入</a></div><div class="field-item odd"><a href="/tags/%E8%A8%98%E6%86%B6%E9%AB%94%E8%B6%8A%E7%95%8C%E8%AE%80%E5%8F%96">記憶體越界讀取</a></div><div class="field-item even"><a href="/tags/use-after-free">Use After Free</a></div><div class="field-item odd"><a href="/tags/prossimo">Prossimo</a></div><div class="field-item even"><a href="/tags/nsa">NSA</a></div></div></div>