如何在軟件開發中避免出現漏洞

隨着數據泄露事件的頻繁發生,創建和維護安全的軟件產品對於每一個組織來說,都變得越來越重要了。儘管並非所有的攻擊都可以被預期或防範,但是我們至少可以通過消減軟件的漏洞,來避免攻擊的暴露面。

在本文中,您將瞭解一些最爲常見的軟件漏洞,以及如何避免它們的方法。此外,您還會學習到如何採用一些通用的優秀實踐,來確保軟件和數據的安全。

常見的軟件漏洞

2019年,MITRE.org的CWE(Common Weakness Enumeration,通用缺陷列表)推出了25項最危險的軟件錯誤列表,請參見:https://cwe.mitre.org/top25/archive/2019/2019_cwe_top25.html。儘管攻擊者的手法五花八門,但實際上卻是萬變不離其宗地組合了各種常見的攻擊方式。在此我們將重點討論其中的幾個常見軟件漏洞。

緩衝區溢出(Buffer Overflow)

當您的程序試圖讀取或寫入超出範圍的緩衝區時,就會發生緩衝區溢出的錯誤。其直接的危害是:可能導致數據覆蓋,或是在現有的代碼中附加不該出現的數據。因此,緩衝區溢出可以使得攻擊者通過執行代碼,來更改程序流,進而讀取某種敏感數據,或造成系統的崩潰。

緩衝區溢出漏洞的典型示例包括:

  • 接受各種長度不受限制的輸入
  • 允許從有效的索引處對數組進行讀取操作

緩衝區溢出漏洞通常潛藏在軟、硬件體系架構的設計、實施、以及操作階段。這些漏洞最常見於C、C ++和Assembly程序中。當然,它也可能出現在缺乏對內存管理提供支持的任何一種編程語言裏。

針對緩衝區溢出漏洞的預防措施

如上文所述,我們應當儘量選擇諸如:Java或Perl等具有防範,或降低此類漏洞風險機制的語言。而在C#之類的編程語言中,我們千萬不要禁用溢出保護的選項。即便如此,那些具有“免疫”功能的編程語言,也可能會在運行環境中的易受攻擊的、原生代碼交互時,產生不可預期的錯誤。

爲了防止緩衝區溢出漏洞被利用,您可以使用諸如Visual Studio或StackGuard之類的編譯器,來針對函數或擴展名進行輸入的限制。同時,您還可以使用各種工具,在內存中隨機地排列程序的不同組件,以使得地址更難以被識別與預測,進而使攻擊者難以利用到這些特定的組件。

另外,請創建代碼時確保正確地分配緩衝區空間,並使用各種方法和功能來限制輸入的大小。

不當的輸入驗證(Improper Input Validation)

如果我們不能夠在接收端對用戶的輸入採取驗證,或驗證不足,那麼就會產生所謂的“輸入驗證不當”。而不當的驗證則會使得攻擊者通過執行惡意代碼,來更改程序流,訪問敏感數據,以及濫用現有的資源分配。

不當驗證的典型示例包括:

  • 自認爲攻擊者無法訪問到隱藏的表單字段
  • 僅驗證輸入的字段的長度,而不是具體內容

不當的驗證同樣會潛藏在軟、硬件體系架構的設計和實施階段。它可以發生在任何接受外部數據的編程語言或系統中。

不當驗證漏洞的預防措施

我們應該對任何用戶採取“零信任(zero trust)”的原則,並假設所有的輸入都是可疑的,直到它們被證明是安全的爲止。同時,我們可以使用白名單機制,來確保輸入的內容僅包含了可接受的格式與信息。

因此,在驗證輸入時,請評估其長度、類型、語法、以及邏輯上的符合性(即:輸入是否具有語義)。您可以使用多種工具來確保完成了充分的驗證,例如:OWASP ESAPI Validation API(https://owasp.org/www-project-enterprise-security-api/)和RegEx(RegularExpression,正則表達式)。這些工具可以幫助我們驗證所有的輸入源,包括:環境變量、查詢、文件、數據庫、以及API調用。

此外,我們應當確保在客戶端和服務器端都執行相應的檢查。爲了避免出現客戶端驗證被繞過的情況,我們需要重點在服務器端捕獲各項輸入,以識別攻擊者的潛在操縱。同時,在程序代碼進行任何必要的組合或轉換後,也請您再次驗證其輸入。

信息泄露(Information Exposure)

數據被有意或無意地提供給潛在攻擊者,被稱爲信息泄露。除了泄露敏感的數據信息,向攻擊者提供可能被利用的軟、硬件環境信息也是一種泄露。

信息泄露的典型示例包括:

  • 錯誤地暴露文件或程序的完整路徑
  • 程序的錯誤、異常消息中暴露了數據庫中用戶的相關信息

信息泄露漏洞依然會潛藏在軟、硬件體系架構的設計和實施階段。它跟編程語言無關,更大程度上取決於編程的習慣。

信息泄露漏洞的預防措施

爲防止信息的泄露,您應當在設計程序架構時,針對明確的信任邊界區域(請參見:https://www.microsoft.com/en-us/itshowcase/implementing-a-zero-trust-security-model-at-microsoft),來保護敏感的信息;通過使用訪問控制,來保護和限制“安全”區域與各個端點之間的連接。

爲了最大程度地避免該漏洞,請在程序中驗證各類錯誤的提示消息,以及用戶警告信息中是否包含有不必要暴露的內容。同時,您還應該限制在URL和通信包的頭部(header)出現的敏感信息。例如:您可以隱藏完整的路徑名稱,以及API密鑰。

特權或認證不當(Improper Privileges or Authentication)

如果未能正確地分配,跟蹤,修改或驗證用戶的相關權限和憑據,那麼就可能發生特權或身份驗證不當的情況。此類漏洞可以讓攻擊者濫用特權,執行受限的任務,以及訪問受限的數據。

特權或身份驗證不當的典型示例包括:

  • 未及時回收臨時的提權
  • 僅通過黑名單、而不是白名單來限制特權
  • 允許較低的特權級別去影響較高的特權帳戶,例如:重置管理員的密碼
  • 限制登錄嘗試的次數或會話空閒時間

特權或身份驗證漏洞仍然可能發生在軟、硬件體系架構的設計、實施、以及操作階段。它同樣不限於某一種編程語言。

特權或身份驗證漏洞的預防措施

您應當將“最小特權原則”,應用於與目標軟件和系統交互的所有用戶和服務之中。只給真正需要某些資源和操作的用戶或服務,完成所需任務的最少權限。我們需要通過在整個程序和環境中使用訪問控制,來限制用戶和實體的權限。

如有可能,我們也可以將高級特權分給多個角色。通過分離,我們可以有效地削弱“高級用戶”,並降低攻擊者濫用其訪問權限的能力。此外,您還可以運用多因素身份驗證的方法,來防止攻擊者繞過系統的檢查機制,輕鬆地獲得訪問權限。

減少一般性漏洞的優秀實踐

除了採取針對特定漏洞的措施之外,我們還應該利用一些通用的措施,在總體上減少漏洞的暴露面。您可以從如下方面入手:

從威脅情報中學習

持續監控和使用來自漏洞數據庫(vulnerability databases,請參見:https://vuln.whitesourcesoftware.com/)和獨立監督組(如:OWASP或NIST)的消息。這些資源可以在出現漏洞後,及時地爲您提供該漏洞的相關信息,並能夠指導您如何解決或緩解當前存在的問題。據此,您可以根據實際情況,準確地修補目標系統及其組件。

謹慎地包含依賴性

請確保僅在需要時纔去使用那些已經過審覈、且值得信任的庫和框架。某些不知名的工具會將其自身的漏洞傳遞到您的軟件中,並且會給攻擊者提供潛在的訪問後門。而且,在使用選定的庫和框架時,請確保您已經充分了解了可用的功能,以及那些已知的漏洞與缺陷。

執行漏洞評估

永遠不要盲目地認爲自己的程序已經“固若金湯”,請不斷通過靜態代碼和動態運行時(runtime)的測試,以確保各種遺留的漏洞能夠得到及時的評估。只有將自動測試工具集成到現有開發環境中,您才能儘早地發現漏洞。據此,您可以確保自己不會因爲時間的限制而跳過某些重要的測試,也不會因爲人爲的錯誤而忽略掉應有的測試。

總結

綜上所述,軟件漏洞可謂層出不窮,顯然無法趕盡殺絕。我們能做的只有通過了解漏洞的原理和防範的措施,來及時地調整自己的實現方式,並開展全面的測試,儘量在產品發佈之前,儘可能多地發現並解決潛在的漏洞與問題。希望本文在上面所介紹到的各種最常見漏洞,以及在軟件開發中推薦採用的實踐和方法,能夠幫助您減少攻擊者乘虛而入的機會。

發佈了32 篇原創文章 · 獲贊 470 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章