1. 程式人生 > >靜態程式碼分析與程式碼質量安全

靜態程式碼分析與程式碼質量安全

HeartBleed Bug

Heartbleed漏洞,這項嚴重缺陷(CVE-2014-0160)的產生是由於未能在memcpy()呼叫受害使用者輸入內容作為長度引數之前正確進行邊界檢查。攻擊者可以追蹤OpenSSL所分配的64KB快取、將超出必要範圍的位元組資訊複製到快取當中再返回快取內容,這樣一來受害者的記憶體內容就會以每次64KB的速度進行洩露。

image

image

image

程式碼靜態分析

• 定義:在不執行計算機程式的條件下,對原始碼進行分析,找出程式碼

缺陷

• 執行方式:一般配合靜態程式分析工具進行

• 採用技術:資料流分析、機器學習、語義精簡...

• 可檢測型別:死鎖,空指標,資源洩露,緩衝區溢位,安全漏洞,競態條件...

• 優點:

• 能夠檢測所有的程式碼級別的可執行路徑組合,快速,準確

• 直接面向原始碼,分析多種問題

• 在研發階段開始找到並修復多種問題,節省大量時間/人力成本

• 注意:靜態分析不是萬能的,測試是持續的過程,非一勞永逸

存在問題

• 編譯器警告: 保證型別安全
– 最初級的靜態分析,檢測規則簡單
• 中間語言分析: 檢測位元組碼( Byte Code )的缺陷,將其重新對映到真實程式碼中
– 在轉換與對映過程中易造成精度丟失
• 高誤報率:目前靜態分析產品的誤報率普遍在30%以上。
• 缺陷種類較少,找到的問題級別不高:多數為程式碼規範或低階缺陷,非實際Bug
– 如命名規範、類定義規範,最佳實踐.....
• 易用性較低:基本上都是一次性的使用工具,無法與SDLC整合
– SCM整合:如SVN,CVS,Perforce,Git
– Bug Tracking:如Bugzilla,Jira

改進型的靜態分析方案

基於Meta Compilation的靜態分析:
• 由斯坦福大學教授Dawson Engler提出,在深度理解程式碼與程式語義的基礎上檢測缺陷
• 旨在查詢“真正的程式碼缺陷”
• 實現原理:
• 使用可擴充套件的metal語言定義正確性Checker
• 將程式的原始碼使用狀態機進行抽象描述(State Machine Abstraction)。
• 使用xgcc系統匹配Checker與抽象狀態機狀態,找到問題所在的點。
• 可準確檢測實際的Bug(記憶體和指標問題、資源洩露、緩衝區溢位,陣列越界,
心臟出血漏洞...)
• 能夠檢測高達億行級別的程式碼庫,避免“狀態爆炸”
• 使用模型檢驗與符號執行技術,誤報率降低至15%以下
• 演算法已步入實際應用
• 面向企業的Coverity 軟體
• 面向開原始碼的Coverity SCAN

如何進行Java程式碼靜態分析?


Java語言被編譯成JVM bytecode - 在執行時被轉換成本地可執行
程式碼的分析
選項一
• 分析 byte-code:使用者編譯他們的軟體,然後分析編譯後的可執行檔案與除錯資訊,分析引擎聯絡找到的缺陷與原始碼位置
• 某些開源工具的實現原理
選項二:
• 獲取所有的Java編譯過程並執行分析
• Bytecode分析工作仍舊存在,但包含更多的內容

基本的工作流

• 獲取所有編譯過程
• 每當 “javac(或其他相關API)” 被呼叫後,編譯獲取系統記錄所有的編譯器選項,操作,原始碼與呼叫的庫檔案
• 面向原始碼和庫檔案可進行全面編譯後分析
• 找到的缺陷將被展示給研發人員修復

如何分析缺陷?

• 過程間分析(Intra-procedural analyses)將考慮每一個合理的可執行路徑
• 快速修剪不可行路徑是一件很麻煩的事情!
• 數學方案
• 獲取一系列的函式定義
• 資源分配
• 呼叫….
• 過程間分析
• Bytecode 分析將建立函式定義

找到潛在Bug其實只是難題之一

• 消除誤報非常難
• 將複雜的缺陷解釋出來很難
• 只找潛在的一次性缺陷是很難的

image

Java 缺陷

Web 應用安全缺陷(OWASP Top 10)
– 跨站指令碼攻擊
– SQL 注入
– 命令列注入
– 路徑遍歷…
資源洩露
– 資料庫連線資源洩露
– 資源洩露
– Socket & Stream 洩露
併發資料訪問異常
– 變數非原子更新
– 雙重檢查鎖定
– 資料競態條件
– Volatile非原子更新
– Servlet 屬性無效鎖定
– 單例模式競態條件
程式假死
– 執行緒死鎖
– 死鎖
空指標引用
– Null檢查後引用空指標
– 直接引用返回的空指標
– Null檢查前引用空指標
API 使用錯誤
– 無效迭代器使用
– 不可修改的集合錯誤
– 已釋放資源呼叫
效能缺陷
– 低效率方法使用
– 在迴圈中連線字串
– 冗餘同步
邏輯錯誤
– 不可達程式碼
– 未使用變數
– 常量表達式
– 非本地資源不當使用
– 整數溢位
– 不當分號

類層次結構不一致
– 呼叫 super.clone() 或 supler.finalize()失敗
– 父函式呼叫丟失
– 建構函式中使用虛擬函式
控制流缺陷
– 在Finally模組中返回
– Switch語句中break丟失
錯誤處理缺陷
– 未驗證的返回值
資料庫操作
– 不正確的實體雜湊
– Load函式返回值錯誤驗證
– 不完全持續週期
– get()不當使用
程式碼可維護性缺陷
– 呼叫已過期方法
– 顯式垃圾收集
– 非靜態方法中設定靜態變數
– 複製/貼上錯誤
– 不可達程式碼
可疑程式碼
– 引數次序錯誤
– 格式錯誤

C# 缺陷 Powered by Eric Lippert

資源洩露
– 資料庫連線資源洩露
– 資源洩露
– Socket & Stream 洩露
API 使用錯誤
– 已釋放資源呼叫
併發資料訪問異常
– 變數非原子更新
– 資料競態條件
效能缺陷
– 低效率方法使用
– 在迴圈中連線字串
– 冗餘同步
程式假死
– 執行緒死鎖
– 死迴圈
可疑程式碼
– 複製/貼上錯誤
– 引數次序錯誤
– 格式錯誤
類層次結構不一致
– 呼叫 base.close() 或 base.dispose()失敗
– 父函式呼叫丟失
控制流缺陷
– 可疑的額外分號
– 不一致比較
– 不相容的型別比較
空指標引用
– Null檢查後引用空指標
– 直接引用返回的空指標
– Null檢查前引用空指標
算術錯誤
– 錯誤移位操作
– 不正確的表示式
– 表示式計算過程中溢位

image

image

C/C++ 缺陷

資源洩露
• 記憶體洩露
• Microsoft COM 記憶體洩露
• Object資源洩露
• 不當delete
未初始化變數
• 返回語句丟失
• 未初始化的指標/標量/陣列 讀寫
• 類或結構體中未初始化的資料成員
併發缺陷
• 死鎖
• 競態條件(Race conditions)
• 阻塞呼叫誤用
算術錯誤
• 負變數不當使用
• 異常符號擴充套件
• 整數溢位
• 除零異常
記憶體崩潰
• 記憶體訪問溢位
• 字串長度計算錯誤
• 緩衝區溢位
• 寫指標溢位
• 負陣列索引寫入
• 記憶體錯誤分配
• 錯誤的記憶體釋放
非法記憶體訪問
• 不正確的delete操作
• 溢位指標讀取
• 越界讀取
• 返回指標至本地變數
• 負陣列索引讀取
• 已釋放指標讀/寫
• 不相容的指標轉換
控制流缺陷
• 邏輯/結構死程式碼
• Switch語句中break遺失
• 非本地資源不當使用

程式假死
• 死迴圈
• 雙重鎖或解鎖丟失
• 負迴圈邊界值
• 執行緒死鎖
• 持鎖過程中呼叫sleep()
空指標引用
• Null檢查後引用空指標
• 直接引用返回的空指標
• Null檢查前引用空指標
錯誤處理缺陷
• 未驗證的返回值
• 未獲取異常
• 負變數不當使用
程式碼維護性缺陷
• 多返回語句
• 無效變數
異常程式碼
• 複製/貼上錯誤
• 格式錯誤
不安全的資料處理
• 不可信的迴圈資料來源
• 使用非可信資料來源讀寫陣列/指標
• 使用非可信資料來源格式化字串
效能缺陷
• 值傳遞大引數
• 使用大堆疊
安全措施違反
• 緩衝區溢位
• 固定長度緩衝區寫入
• 非安全函式呼叫
• 非安全臨時檔案使用
• 檢查/使用時間不一致
• 使用者空間指標不當使用
API錯誤使用
• 非安全chroot呼叫
• 錯誤的迭代器使用
• printf() 引數不匹配

image

檢測例項-HeartBleed Bug

image

Jenkins檢測對比

image

Freeradius缺陷檢測對比

image

imageimage

image

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

如有想了解更多軟體研發 , 系統 IT整合 , 企業資訊化,專案管理,企業管理 等資訊,請關注我的微信訂閱號:

MegadotnetMicroMsg_thumb1_thumb1_thu[1]


作者:Petter Liu
出處:http://www.cnblogs.com/wintersun/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。
該文章也同時釋出在我的獨立部落格中-Petter Liu Blog