搜尋此網誌

2009年9月30日 星期三

[工具介紹] Java程式檢測工具 (二) - FindBugs

前言

FindBugs 同樣是用來檢測 Java 程式的工具,其檢測的對象是 Byte Code (class 或是 jar 檔)。儘管如此,FindBugs 依舊是屬於靜態分析的方式。FindBugs 如其名,主要是利用 Bug Patterns 的概念,找尋出程式中有問題 (Bugs) 的程式碼 。在其官方的網站中提到 Bug Patterns 的產生可能有下列因素:

  • 程式語言本身不容易使用的功能 (Difficult language features)
  • 被誤用的 API (Misunderstood API methods)
  • 當程式碼在維護時,不變的條件被誤解了 (Misunderstood invariants when code is modified during maintenance)
  • 其他常見的錯誤,例如打錯字、或是使用了錯誤的布林運算元 (Garden varieity mistakes: typos, use of the wrong boolean operator)

FindBugs 本身提供完整的 GUI 介面,讓使用者可以很方便地進行檢測的工作。因為 FindBugs 主要使用 Java 進行開發,所以可以運行於各種的作業系統上。雖然 FindBugs 是針對 ByteCode 進行掃描,但是在 GUI 中我們可以指定原始程式碼所在的目錄。如此一來, FindBugs 就會自動將發現問題的 ByteCode 與原始程式碼自動連結並加以顯示。

點選 Bug 後可以自動顯示出 Bug 所在的程式碼gui 001

除了 GUI 的操作方式外,FindBugs 也支援 Ant 的開發環境。而在與 IDE 整合方面,則僅提供 Eclipse 的 Plug-in。也因為 FindBugs 支援 Eclipse 的 Plug-in,接下來我會直接使用 Eclipse 的 Plug-in 作為範例說明。不過在此之前,我先提醒一下在使用 GUI 時有兩個需要特別注意的地方。第一個是如果在進行分析時進度忽然停滯不動,有可能是因為記憶體使用量已經超過限制,此時需要增加 JVM 記憶體的使用量 (-Xmx)。另外一個就是在 Microsoft Windows 下我一直沒有辦法正確的連結到原始程式碼。

安裝 Eclipse 的 Plug-in

  1. 選取功能選單的 Help –> Install New Softwarepmd 001
  2. 點選 “Add…” 按鈕,輸入下列資料後按下按鈕 “OK”。 install 001
  3. Work with 的下拉選單中選取 FindBugs – http://findbugs.cs.umd.edu/eclipse  ,點選後需要等待一段時間。
  4. 點選 FindBugs 後按下按鈕 “Next >”,點選後需要等待一段時間。 install 002
  5. 選取 FindBugs Feature 後按下按鈕 “Next >”。install 003
  6. 選取 I accept the terms of the license agreement 後按下按鈕 “Finish”。 install 004
  7. 等待安裝畫面執行完畢。 pmd 006
  8. 安裝完畢後按下 “Yes” 按鈕重開 Eclipse 以使 FindBugs Plug-in 生效。 pmd 007

使用 FindBugs 檢測 Struts 程式碼

  1. 在程式碼 (或專案) 的目錄下使用滑鼠右鍵叫出功能選單,選取 Find Bugs –> Find Bugsworking 001
  2. 等候 Find Bugs 檢測完畢。working 002
  3. 檢測完畢後會跳出一個視窗詢問是否切換至 FindBugs 的 perspective,先選 Yesworking 003
  4. 在FindBugs perspective的左上角出現 Bug Explorer,將發現的問題依據不同的原因加以分類,可以很快的了解有哪些問題需要進一步處理。working 004
  5. 但是 FindBugs perspective 在操作上有些不順暢的地方,右邊的 view 也有被切掉的情形,因此我們切換回 Java perspective。

    利用右上方的按鈕切換回Java perspective

    switching perspective 
  6. FindBugs 的檢測結果顯示於 Problems view。working 005 
  7. 在發現的 Bug 上點選右鍵叫出功能選單,選取 Properties 以顯示問題的詳細資訊。working 006
  8. Message 欄位顯示問題的描述。working 007 
  9. Category 欄位顯示 Bug 的分類working 008 
  10. 上述的資訊雖然很完整,但是卻過於分散不容易閱讀。我們可以利用在警告圖示點選右鍵的功能選單上,選取 Show Bug Details 以顯示 Bug 相關資訊。working 009 
  11. 雖然顯示的資訊較少,但是可以一眼看到 Bug 的類別與說明,方便了解問題與後續處理方式之判斷。working 010 

設定 FindBugs 的檢測項目

我們可以利用專案的 Properites 設定畫面,進行 FindBugs 的相關設定。主要設定項目包含是否自動執行 FindBugs 檢測項目 (Run automatically)以及檢測項目的相關設定。雖然自動執行 FindBugs 檢測項目相當方便,但是因為 FindBugs 檢測需要一段不算短的時間,所以勾選時請加以三思。如果有必要,請記得讓 FindBugs 的檢測在背景執行,設定方式為在 FindBugs 的執行畫面選取 Always run in background。檢測項目設定部分可以指定哪些檢測項目需要執行,這樣的設計比 PMD 使用上來的更為方便。此外也可以設定報表與過濾器 (Filter) 相關之選項,過濾器主要是用來告知 FindBugs 那些項目 (如類別) 不需要統計在結果的報告中。

FindBugs 設定畫面 (專案的 Properties 畫面) 

setting 001

當使用自動執行 FindBugs 時,請勾選 Always run in background 以免等待過長的時間。working 002

Bugs 的處理

透過 FindBugs 找出問題後,我們同樣需要確認是否需要進行修正。如果我們認定不需要修正,那麼有下列幾個方法可以告知 FindBugs 不需要把這個問題放入警告中。

  1. 利用過濾器的機制。使用方法為在特定的問題上點選滑鼠右鍵,然後執行 Toggle Filter –> This Specific Bug Pattern。再次點選可以讓此類問題再次被加以警告。實際上此操作方法將使得同一種類的問題都被加以忽視,而不是針對單一問題,所以使用上並不方便。過濾器除了可以透過此一介面加以設定外,也可以在專案設定畫面中指定外部的設定檔。此外部檔案除可同步用於 Ant 的環境下外,而且可做更細緻的設定,而非僅能針對同一類別下的所有問題。working 011
  2. 利用 Annotations 的機制,宣告哪些函式/類別/參數等不需要提出警告 (SuppressWarnings)。使用上除了無法透過 Eclipse Plugin 操作介面的指令直接產生外,同樣也無法針對單一的問題加以宣告。

    宣告 equals 函式不要產生警告訊息annotation 002
  3. 透過 GUI 提供的功能,我們可以將找到的問題加以分類,並且填上相關說明。在使用上最為方便,功能也最為完整。但是卻僅能操作於 GUI 的環境,而無法在 Eclipse Plug-in 加以使用。這些資訊可以連同檢測結果一併儲存下來,以便日後的檢視與分析。dealing 001

報表

FindBugs 提供不同的分析能力,包含能夠將多個檢測結果加以整合 (union bugs)、統計多次的檢測結果 (compute bug history)、選取特定的問題 (filter bugs)、計算問題的密度 (defect density)等等。這些工作可以透過 Ant 加以執行,另外也提供命令列的執行方式 (for /bin/sh)。FindBugs 在這方面的能力優於 PMD 所提供的功能,尤其是統計多次檢測結果的能力,可以方便管理者做追蹤的動作。

Annotations

Annotations 除了可以用來告知 FindBugs 哪些項目不需要進行警告外 (SuppressWarnings),還可以告知 FindBugs 那些項目應該做何檢視。我們用一個假想的例子加以說明。在範例程式中,首先我們宣告 print 函示的參數 (sb) 有可能是 null (CheckForNull),所以 FindBugs 會發現到我們使用 sb 時並沒有先做是否為 null 的判斷,因此產生了警告的訊息。除此之外,我們也宣告呼叫 reverse 這個函數的回傳值需要被檢查 (CheckReturnValue)。同樣的,因為我們的程式在呼叫 reverse 時並沒有檢查回傳值,所以產生了警告的訊息。透過 Annotations 的機制,可以強制 FindBugs 進行我們所需的檢查項目,以避免一些將來可能發生的潛在問題。

annotation 001

結語

FindBugs 在進行檢測時所花費的時間比較多 (與 Eclipse 或 PMD 相較),其檢測出來的問題數也相對較少。這並不代表 FindBugs 的效果較差,只能說是目的不同。我個人覺得最可惜的是在與 IDE 整合方面仍有很大的改進空間。唯一支援的 Eclipse Plug-in,在使用上連問題的處理都無法有效進行,倒是在資訊的呈現相當詳盡。既然官方網站也說 Eclipse Plug-in 還在測試階段,就讓我們對其日後的表現拭目以待。在此之前,使用 GUI 來進行檢測是一個折衷的辦法。此外,報表的功能可以做歷史記錄的追蹤,這點對於程式碼的管理有其一定的作用。同樣可惜的是必須透過 Ant (或命令列) 的形式才有辦法產生報表,在使用上的親和力同樣略嫌不足。

2009年9月29日 星期二

[工具介紹] Java程式檢測工具 (一) - PMD

前言

PMD 是來執行 Java 程式檢測的工具,檢測的對象是原始程式碼。雖然 PMD 看起來像是一個縮寫字,但是作者表示當初採用這個字純粹只是因為這幾個單字念起來很順口。根據網站上面的介紹, PMD 可以找出下列問題:

  • 疑似的臭蟲 (possible bugs),例如空的 try/catch/finally/switch 描述句。
  • 無法執行的程式碼  (dead code),例如未使用的 local 變數、參數、或是 private 函數。
  • 不良的程式碼 (suboptimal code),例如效率不良的使用 String/StringBuffer
  • 過於複雜的語法 (overcomplicated expressions),例如不必要的 if 描述句,可以用 while 迴圈取代的 for 迴圈。
  • 重複的程式碼 (duplicated code),剪貼的程式碼表示臭蟲也被複製了。

PMD 本身沒有提供圖形化的介面,而必須透過命令列的方式加以操作。當然在支援 Ant 方面, PMD 是沒有問題的。除此之外,更支援 Maven 1/2 的開發環境。而對於多數程式開發人員關心的 IDE 支援度方面,幾乎市面上主要的 IDE 都受其支援。以此看來,要在大多數的開發環境下使用 PMD 幾乎是沒有甚麼門檻。

接下來我就以 Eclipse 的 Plug-in 使用方式作為說明範例。

安裝 Eclipse Plug-in

  1. 選取功能選單的 Help –> Install New Softwarepmd 001
  2. 點選“Add…” 按鈕,輸入下列資料後按下按鈕“ OK”。pmd 002
  3. Work with 的下拉選項中選取  PMD – http://pmd.sf.net/eclipse  ,點選後需要等待一段時間。
  4. 點選 PMD for Eclipse 3(使用 Eclipse 2 的人請選擇 PMD for Eclipse 2)後按下按鈕“Next > “ ,點選後需要等待一段時間。pmd 003
  5. 選取  PMD Plug-in 後按下按鈕 “Next > “。pmd 004
  6. 選取  I accept the terms of the license agreement 後按下按鈕 “Finish”。pmd 005
  7. 等待安裝畫面執行完畢。pmd 006
  8. 安裝完畢後按下 “Yes” 按鈕重開 Eclipse 以使 PMD Plug-in 生效。pmd 007

使用 PMD 檢測 Struts 程式碼

  1. 在程式碼的目錄下使用滑鼠右鍵叫出功能選單,選取  PMD –> Check Code with PMDpmd 008
  2. 等候 PMD 檢測完畢。pmd 009
  3. 檢測完畢後會多出兩個視窗,分別為 Violations Overview 與 Violations Outline。
  4. Violations Overview 視窗內容為各 package 與各檔案所產生的違規事件 (Violations) 數量統計,其中 Violations/LOC 與 Violations/Method 數據必須先點選該 package 後才會產生(或點選Calculate statistics按鈕,此按鈕位於五個不同顏色按鈕的左方)。此外可以透過右上方五個不同顏色的按鈕,選擇只統計特定等級的違規事件。PMD 將違規事件依重要性依序分為 error high, error, warning high, warning, information 五種等級。 pmd violations overview
  5. Violations Outline 則依據使用者所點選的檔案顯示該檔案的各項違規,圖示範例為 org.apache.struts2 下的 ServletActionContext.java。點選特定一筆資料後會自動跳到該行程式碼。pmd violations outline
  6. 比較 ServletActionContext.java 在使用 PMD 前後可以發現警告的數量從原先的 3 個變成了 11 個,其中還包含 1 個錯誤 (第 42 行)。

    使用 PMD 前的警告資訊

    servlet action context without pmd

    使用 PMD 後的警告資訊,其中第 42 行產生錯誤。而第 50 行雖同時被 Eclipse 與 PMD 標示為警告(違規),但其警告原因卻不相同servlet action context with pmd
  7. 查看 org.apache.struts2.components 下的 AppendIterator.java ,我們發現第 125 行雖然同時被 Eclipse 與 PMD 標示出來,但是不但標示原因不同,連標示等級都不一樣。PMD 將 125 行標示為錯誤。 append iterator with pmd

設定 PMD 的檢測項目

經由上述的實際範例中我們可以看到透過 PMD 的檢測將會發現許多違規事件,但是當我們進一步加以檢視後可以發現其中不少違規事件其實跟錯誤沒有關係。為了避免過多無謂的違規事件影響我們發現真正的問題,我們可以透過下列幾個方法。

  1. 利用前述 Violations Overview 的功能,僅顯示特定等級的違規事件。
  2. 第一種方法雖然方便,但是其僅能影響統計數據,包含 Violations Outline 與程式碼的警告訊息都不會消失。要讓這些資訊消失的方法就是設定 PMD ,修改其檢測的項目。
    1. 點選 Window –> Preferences
    2. 點選 PMD –> Rules Configuration
    3. 點選想要修改或刪除的規則後,點選按鈕 ”Edit rule…” 或是  ”Remove rule”。
    4. 需要特別注意的是如果要 PMD 不檢測特定的規則,必須直接將規則刪除,而沒有辦法告知 PMD 跳過此一檢測規則。因此最好能夠在進行動作前做好規則的備份 (Export rule set…),以免日後要重新檢測該規則時已經找不到了。
    5. 透過此一畫面也可以進行規則的新增。
    6. 設定完成後按下按鈕 “OK”。
    7. 在程式碼目錄上點選滑鼠右鍵叫出功能選單,點選 PMD –> Clear PMD Violations 將之前的違規訊息加以清除。
    8. 在程式碼目錄上點選滑鼠右鍵叫出功能選單,點選 PMD –> Check Code with PMD ,以便依據新的規則重新進行檢測。
  3. 雖然第二種做法可以減少很多看似不重要的警告訊息,但是也有可能因此將疑似的問題隱藏起來。之間的取捨,就需要仔細的加以評估。例如我們看到 PMD 在 org.apache.struts2.views.xslt 下的 StringAdapter.java 標示出第 78 行的 node 變數連續被指定兩次,是一項違規事件,而等級是最不嚴重的 information 。我們透過實際檢閱程式後,發現此處用法的結果是我們想要的。但是在某些時候,這樣的用法可能代表了程式有漏寫或是其它的錯誤。如果我們因為認為這種情況不重要,甚至是認為 information 等級的違規事件不重要而將此規則刪除,可能就真的失去了找到問題的機會。 比較好的做法不是直接刪除檢測的規則,而是採用 Supressing Warning 的機制。

    node 變數連續被指定兩次的行為,被 PMD 標示為違規事件
    string adapter

違規事件的處理

透過 PMD 找出違規事件後,我們需要先決定是否要修正特定的違規事件。判斷的依據除了根據程式本身決定是否違規事件將會產生問題外(這些通常是所謂誤判),有更多時候是必須依據自我程式開發的原則。原因在於這些違規事件很多是因為沒有遵守所謂的良好寫作習慣所產生,但是這些良好的寫作習慣卻不見得在任何時候都可以適用。當然我們還是希望在大多數的情況下能夠盡量加以遵守這些習慣,以免日後產生一些”很奇怪”的問題。此外,除非你針對良好的程式寫作方式做過訓練,不然大多數的違規事件對一般程式設計師來說可能不容易馬上理解。針對此一問題,在  Violations Outline 的畫面中可以在特定的錯誤訊息上點選滑鼠右鍵叫出功能選單,此時有一個 Show Details 的選項,點選後會出現違規事件的說明。透過此畫面可以讓我們知道發生違規的原因,如此一來就能幫助我們決定是否要修改此一違規事件,以及如何加以修改。show details

除了進行修改外,有時候我們的決定是不進行修正。此時我們必須透過 Suppressing Warnings 的機制,告訴 PMD (以及其他團隊成員) 此一違規事件不需要再加以提示。操作方式為透過  Violations Outline 的畫面在特定的錯誤訊息上點選滑鼠右鍵叫出功能選單,之後選取 Mark as reviewed 選項就可以讓此一違規事件加以排除。如果我們注意看程式碼的部分,會發現 PMD 在發生違規事件的程式碼後面加上了 // NOPMD by xxxxx xxxx 之類的字樣。這是 PMD 用來 Suppressing Warnings 的方式之一,另外也可以透過 Annotation 的方式來達到同樣的目的,只可惜透過 Eclipse 的 Plug-in 無法使用 Annotation 的方式。而使用 Plug-in 的最大問題在於它不會強迫程式設計師輸入原因加以說明,所以將會造成日後維護上的極大困擾,此部分必須靠程式設計師的自制能力加以彌補。violations menu

當我們將違規事件標示為 reviewed 之後,並不會馬上從 Violations outline 畫面中消失。不過當日後再次進行檢測時,這些已經 reviewed 過的違規事件就不會再出現了。

找出重複的程式碼

重複的程式碼一直以來是一個很嚴重的問題。我所謂的嚴重不只在於這是一個很常見的問題,更在於其所衍生後續維護的問題之嚴重性。 其實這個問題很容易了解,要避免的方法也很簡單,但是我相信即使在未來依舊很難加以消除,因為貪圖方便(剪貼)是大多數人的自然天性。 PMD 有一個比較少見的功能,就是可以找出疑似重複的程式碼。操作方式如下:

  1. 操作方式跟之前有所不同,必須在專案上(而不是程式碼目錄上)點選滑鼠右鍵叫出功能選單,然後透過 PMD –> Find Suspect Cut And Paste 的選項加以進行。cdp invoke
  2. 設定參數主要只有一個,那就是多少行程式碼重複才列入考量 (Minimum Tile-size)。設定好之後,按下按鈕 “OK” 就會進行檢測的工作。cpd setting
  3. 檢測完畢後結果會出現在 CPD View,比較可惜的是此一介面並沒有辦法直接連到程式碼本身,所以如果要進行判斷或修正時需要額外多一些操作步驟。cpd view
  4. 除了 CDP View 之外, PMD 也可以將檢測結果產生於報表中。其預設格式為 txt ,檔案位置則為 reports / cpd-report.txt 。此檔案內容包含重覆程式碼所在的檔案名稱與程式碼行數,另外也包含重覆程式碼的內容。不過因為重複程式碼本身沒有前後文,所以要做為是否需要進行修正的判斷依據有時候仍嫌不足。cpd report 

產生報表

PMD 除了可以產生重複程式碼的報表外,也可以產生違規事件的報表。同樣必須透過在專案上點選滑鼠右鍵叫出功能選單,然後利用 PMD –> Generate reports 的選項加以進行。執行完畢後會在 reports 目錄下產生多個檔案,其中包含 html, txt 與 csv 格式,以方便日後的使用。

JSP支援

雖然 PMD 支援 JSP 的檢測,但是卻無法檢測 JSP 內的 Java 程式碼 (Java Scriptlets)。此外,EL的語法也是無法進行檢測。

Rulesets

PMD 將檢測規則依據屬性與檢測對象的不同,區分為多個 ruleset 。在安裝 Eclipse 的 Plug-in 之後,幾乎所有相關的 ruleset 就已經設定完畢。但是除了這些預設的 ruleset 之外,PMD 也提供了其他的 ruleset (例如給 Android 使用的 ruleset)以備所需的人加以利用。檢視過這些 ruleset 後,我們發現只有一個 ruleset 是跟安全直接相關,名稱為 Sun Security ,而內容只有兩個檢測規則。PMD 是一個不錯的工具,只可惜對於程式安全部份的幫助還是極其有限,期待日後在這部分會有加強的計劃。

結語

PMD 算是一個相當成熟的工具,雖然其針對程式碼的檢測規則還是多屬於良好寫作習慣的建議,而不是針對網站程式的安全,但是卻不能因此就加以忽視。如果以廣義的安全來看,穩定的系統也是安全的一項需求,而穩定來自於寫作良好的程式碼(還有其它因素)。此外,這類工具除了需要熟悉操作外,更重要的是藉此培養程式設計師良好的寫作觀念與能力,這點 PMD 倒是可以提供相當不錯的協助。

2009年9月24日 星期四

[工具介紹] Static Application Scanner for Java

這幾年應用程式(尤其是網站應用程式,Web Application)的安全問題受到各方重視,一些新的、舊的概念,只要跟此議題有所關聯都因此而浮上檯面。包含SSDLC/SDL、WAF、Secure Coding、Application Security Scanner等在內的各式各樣工具或規範,試著從不同的面向去解決程式安全的問題。

Gartner 於今年年初出了一篇有關靜態程式安全掃描的市場分析,分析對象為目前市場上主要的玩家。但是這些產品大多所費不貲(除了整在 IDE 中的形式,可能會有免費使用的陽春功能),而且甚至很多產品在台灣還沒有直接取得的管道。所以我們今天要介紹一些免費的工具,這些工具的共通點就是提供靜態應用程式檢測的功能,而且以 Java 程式語言做為目標。除了可以當作獨立的工具使用外,有些工具還可以透過外掛的方式整合至 IDE (像是 Eclipse),使用上更加方便。除此之外,各個工具之間可說是具有相當的差異性。檢測的對象可能是原始程式碼,也有可能是 Byte Code。而著重的面向也不一樣,可能是原始程式碼的不良結構,也可能是針對程式不合常理的錯誤,又或者是針對不好的寫作方式。這些問題都跟軟體的品質有關,而品質當然也包含了安全的問題。

這些工具都不是以安全做為訴求的出發點,而且大多也不支援網站應用程式,所以僅能當作增進一般應用程式品質/安全的工具之一,而無法有效的面對現今網站程式開發所面臨的威脅。雖說如此,網站應用程式依舊是屬於應用程式的一種,所以其安全性的問題不應只是考慮到網路的部分,包含基本的程式結構等也是我們應當注意的項目。這些工具部分的檢測功能其實 IDE 本身可能就已經具備,但是以目前現況而言,IDE 主要的功能依舊還在不此,所以能夠偵測的項目相對較少。

在這篇文章中,我先列出這些工具的名稱與簡述。簡述皆為從官方網站截取的描述,所以是英文的形式。之後我會針對各個工具撰寫相關的使用說明,說明時除了做功能的介紹外,也會利用實際的應用程式作為範例。採用的應用程式有兩個,一個是 log4j 1.2.15 ,另外一個則是 struts 2.1.6。如果該工具支援 Eclispe 的外掛,我將會以 Eclipse 作為操作的 IDE 環境。因此我先將兩個應用程式的程式碼匯入為 Eclipse 的專案,透過畫面我們可以看到 Eclipse 本身就產生了很多的警告訊息。我個人認為 Eclipse 提供的警告訊息雖然跟程式錯誤與否無關,但是大多數的建議可以讓我們的程式碼更加清楚、更加容易明瞭。對程式碼而言,這是最重要的要求。因為錯誤不只在開發的時候會產生,在後續的維護中更容易產生。透過清楚而易了解的程式碼,可以大幅降低後續維護時產生錯誤的機會。也因此我個人建議這些警告訊息應該先進行處理,之後再利用其他工具找尋其他的問題。

 

將 log4j 1.2.15 的程式碼匯入 Eclipse 中。

eclipse log4j

將 struts 2.1.6 的程式碼匯入 Eclipse 中。

eclipse struts

 

PMD scans Java source code and looks for potential problems like:
  • Possible bugs - empty try/catch/finally/switch statements
  • Dead code - unused local variables, parameters and private methods
  • Suboptimal code - wasteful String/StringBuffer usage
  • Overcomplicated expressions - unnecessary if statements, for loops that could be while loops
  • Duplicate code - copied/pasted code means copied/pasted bugs

Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard. It automates the process of checking Java code to spare humans of this boring (but important) task. This makes it ideal for projects that want to enforce a coding standard.

Checkstyle is highly configurable and can be made to support almost any coding standard. An example configuration file is supplied supporting the Sun Code Conventions. As well, other sample configuration files are supplied for other well known conventions.

Beyond the level of what Javadoc does, DoctorJ compares documentation against code. Among what it detects:
  • misspelled words
  • parameter and exception names:
    • missing
    • misordered
    • misspelled
  • Javadoc tags:
    • invalid
    • misordered
    • missing expected arguments
    • invalid arguments
    • missing descriptions
    • undocumented classes, methods, fields, parameters

ESC/Java2 (Eclipse plugin available)
The Extended Static Checker for Java version 2 (ESC/Java2) is a programming tool that attempts to find common run-time errors in JML-annotated Java programs by static analysis of the program code and its formal annotations. Users can control the amount and kinds of checking that ESC/Java2 performs by annotating their programs with specially formatted comments called pragmas.

FindBugs (Eclipse plugin available)
FindBugs looks for bugs in Java programs.  It is based on the concept of bug patterns.  A bug pattern is a code idiom that is often an error.  Bug patterns arise for a variety of reasons:
  • Difficult language features
  • Misunderstood API methods
  • Misunderstood invariants when code is modified during maintenance
  • Garden variety mistakes: typos, use of the wrong boolean operator
FindBugs uses static analysis to inspect Java bytecode for occurrences of bug patterns.  Static analysis means that FindBugs can find bugs by simply inspecting a program's code: executing the program is not necessary.  This makes FindBugs very easy to use: in general, you should be able to use it to look for bugs in your code within a few minutes of downloading it.  FindBugs works by analyzing Java bytecode (compiled class files), so you don't even need the program's source code to use it.  Because its analysis is sometimes imprecise, FindBugs can report false warnings, which are warnings that do not indicate real errors.  In practice, the rate of false warnings reported by FindBugs is less than 50%.

FindBugs supports a plugin architecture allowing anyone to add new bug detectors.  The publications page contains links to articles describing how to write a new detector for FindBugs.  If you are familiar with Java bytecode you can write a new FindBugs detector in as little as a few minutes.

FindBugs is free software, available under the terms of the Lesser GNU Public License.  It is written in Java, and can be run with any virtual machine compatible with Sun's JDK 1.5.  It can analyze programs written for any version of Java.  FindBugs was originally developed by Bill Pugh and David Hovemeyer.  It is maintained by Bill Pugh, and a team of volunteers.

FindBugs uses BCEL to analyze Java bytecode.  As of version 1.1, FindBugs also supports bug detectors written using the ASM bytecode framework.  FindBugs uses dom4j for XML manipulation.

JeSS is a plugin for the Eclipse IDE. It is a static security scanner for Java source code. The plugin creates an AST for the source code and then uses the visitor pattern to find patterns in the AST that could be possible security bugs.

Hammurapi is a code quality governance platform to mitigate risks of outsourcing of software development.

Hammurapi produces a consolidated report for the entire application. The report identifies most significant problems in the application and allows to navigate to the source of the problem in a few clicks.

Modern applications consist of source artifacts developed in different languages. For example, a typical Java application contains at least Java sources and XML configuration files. A Java-based web application also contains JSP(X) files. With AJAX and Flex gaining popularity, more and more functionality gets developed in JavaScript. Therefore, analysis of just one type of source artifacts is not sufficient for gaining confidence in the application.

Currently Hammurapi can review Java and XML-based artifacts. Support of JavaScript is coming in the first half of 2009.

JAMIT, the Java Access Modifier Inference Tool can be used on Java class-files to infer tighter access modifiers. Tight access modifiers are commonly perceived as good programming practice. Nevertheless, refactoring of code or just ignorance at the time where the code is written often lead to modifiers that are less restrictive than they could be.

More restrictive modifiers help to increase encapsulation, one of the major goals in object oriented program design. They can also serve as a criteria for good software engineering. In some cases, more restrictive modifiers can even help the compiler to produce better (= faster) code.

The most restrictive modifier supported by Jamit is dead. In other words, Jamit can be used to eliminate dead code from Java applications and libraries. In this sense it is similar to JAX. Eliminating dead code with Jamit is easy. You specify the main method, a file that defines native and reflective behavior, the input directory with the original classes and an output directory where the optimized classes are to be written to. The resulting code can often be significantly smaller, especially if the code was using small parts of a larger framework.

JCSC is a powerful tool to check source code against a highly definable coding standard and potential bad code.

The standard covers naming conventions for class, interfaces, fields, parameter, ... . Also the structural layout of the type (class/interface) can be defined. Like where to place fields, either before or after the methods and in which order. The order can be defined through the visibility or by type (instance, class, constant). The same is applicable for methods. Each of those rules is highly customizable. Readability is enhanced by defining where to put white spaces in the code and when to use braces. The existence of correct JavaDoc can be enforced and various levels. Apart from that, it finds weaknesses in the the code -- potential bugs -- like empty catch/finally block, switch without default, throwing of type 'Exception', slow code, ... .  JCSC is inspired by lint.

JCSC features a graphical UI for easy rule configuration, a command line interface, an Ant task which produces a JavaDoc style webpage and is CruiseControl compatible (see screenshot). Also, the NCSS/CCN metrics have been added for easier code quality assesment. Plugin for IntelliJ IDEA enables ad hoc checking from within the IDE. (see screenshot)

Currently JCSC supports over 100 enforceable rules -- this is not all and there is more to come!

Jikes is a compiler that translates Java source files as defined in The Java Language Specification into the bytecoded instruction set and binary format defined in The Java Virtual Machine Specification.

You may wonder why the world needs another Java compiler, considering that Sun provides javac free with its SDK. Jikes has five advantages that make it a valuable contribution to the Java community: [OSI Certified Logo]
  • Open source. Jikes is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative.
  • Strictly Java compatible. Jikes strives to adhere to both The Java Language Specification and The Java Virtual Machine Specification as tightly as possible, and does not support subsets, supersets, or other variations of the language. The FAQ describes some of the side effects of this strict language conformance.
  • High performance. Jikes is a high performance compiler, making it ideal for use with larger projects.
  • Dependency analysis. Jikes performs a dependency analysis on your code that provides two very useful features: Incremental builds and makefile generation.
  • Constructive Assistance. Jikes strives to help the programmer write better code in two key ways. Jikes has always strived to provide clear error and warning text to assist the programmer in understanding problems, and now with release 1.19 Jikes helps point out common programming mistakes as documented in Effective Java.

Jlint will check your Java code and find bugs, inconsistencies and synchronization problems by doing data flow analysis and building the lock graph.  Jlint is extremely fast - even on large projects, it requires only one second to check all classes!  It is easy to learn and requires no changes to the class files.  Jlint has been used in an industrial environment and successfully uncovered faults with little effort!

JPF is a system to verify executable Java™ bytecode programs. In its basic form, it is a Java™ Virtual Machine (JVM) that is used as an explicit state software model checker, systematically exploring all potential execution paths of a program to find violations of properties like deadlocks or unhandled exceptions. Unlike traditional debuggers, JPF reports the entire execution path that leads to a defect. JPF is especially well-suited to finding hard-to-test concurrency defects in multithreaded programs.

While software model checking in theory sounds like a safe and robust verification method, reality shows that it does not scale well. To make it practical, a model checker has to employ flexible heuristics and state abstractions. JPF is unique in terms of its configurability and extensibility, and hence is a good platform to explore new ways to improve scalability.

JPF is a pure Java application that can be run either as a standalone command line tool, or embedded into systems like development environments. It was mostly developed - and is still used - at the NASA Ames Research Center. Started in 1999 as a feasibility study for software model checking, JPF has found its way into academia and industry, and has even helped detect defects in real spacecraft.

2009年9月18日 星期五

[個人意見] 別再只依賴防毒軟體了

根據 Trusteer 近日公布的一項報告分析顯示,幾乎所有的防毒軟體都無法有效地阻擋 Zbot 這個用來竊取網路銀行帳號/密碼的惡意程式。比較使用最新的防毒軟體與不使用防毒軟體的結果發現只改進了 23% 的阻擋效果。Zbot 利用了 rootkit 的技術來躲過防毒軟體的偵測。Zbot 除了會竊取資料外,也會讓受感染的電腦成為僵屍網路的一員,並且具有自我更新的能力。

而另外一份由 Trend Micro 所發布的研究報告中顯示,大多數的電腦一旦被惡意程式感染後,將會持續一段相當長的時間,其中超過 50% 的電腦在被感染 10 個月後依舊沒能將之移除。其實這也難怪,因為如果使用者已經安裝了最新的防毒軟體,通常就不會去考量系統被入侵的可能性。事實上,真要考量也可能無從下手。對於沒有安裝防毒軟體的電腦而言就更不用說了,被持續感染也只是”順理成章”。

針對一些比較刁鑽的惡意程式 (如使用 rootkit 技術加以隱匿),往往我們必須透過其他的安全產品加以防範。例如使用其他開機工具以便進行完整的硬碟掃描,或是利用網路流量分析工具找出可疑的封包與流量。這些外加的方式在使用上可能不若防毒軟體一般方便,但卻是這組防禦體系中不可或缺的一環。傳統防毒軟體的重要性不是完全消失,而是因為其有效性隨著惡意程式的演進而降低,也因此我們再也不能光靠防毒軟體來保護我們的電腦。

 

相關連結:

[研究報告] 95% 的部落格留言、聊天室與論壇的內容是惡意或無用的資料

根據 Websense 日前一份針對網路安全研究報告中提出的數據顯示,有高達 95% 的部落格留言、聊天室與論壇的內容是惡意或無用的資料。雖然使用者的參與 (尤其是提供資料) 造成了 Web 2.0 榮景,但是也同樣成了有心分子用來散佈惡意程式的重要方式之一。

這份報告收集資料的時間為 2009 年上半年,並將分為網站安全、電子郵件安全與資料安全三個部分,關於網站與資料安全有下列的發現:

  • 惡意網站的數量較 2008 年下半年之數量成長了 233%,而跟 2008年上半年相較更是成長了 671%。
  • 藏有惡意程式的網站中,有 77% 是屬於合法的網站。這些網站因為被入侵,而變成了散佈惡意程式的管道。
  • 在前100大的網站中,有 61% 的網站中包含了惡意程式或是導像惡意網站的連結。
  • 95% 的部落格留言、聊天室與論壇的內容是惡意或無用的資料。
  • 提供有關 Sex 網站連結的網頁中,有 50% 藏有惡意程式。
  • 提供像是 Sex、成人內容、賭博、藥物等內容的網頁中,有 69% 包含至少一個以上的惡意連結。
  • 在 2009 年上半年所發現且提供像是 Sex、成人內容、賭博、藥物等內容的新網頁中,有 78% 包含至少一個以上的惡意連結。
  • 網站攻擊行為中,有 37% 會進行資料的竊取。
  • 資料竊取的攻擊中,有 57% 是透過網站進行的。

透過這些數據,我們再次看到網站安全的議題持續惡化中。網站不僅是現今網路攻擊的主要管道,其成長的力道亦相當驚人。而且不像過去以惡意網站為主,現在大量合法網站淪陷為惡意程式的溫床,讓使用者更加防不勝防。使用者與網站擁有者雙方除了多加小心外,更需透過有效的工具才能夠免於惡意程式所帶來的傷害。

 

相關連結:

2009年9月16日 星期三

[研究報告] 企業尚未有效地應付現今的主要威脅

根據 SANS 於近日所公布的一份報告中指出,現今企業所面臨的資訊安全問題主要來自於兩個方面。一個是沒有及時更新的用戶端軟體 (Unpatched client-side software),另外一個則是與網際網路連結的網站 (Internet-facing web sites)。

雖然目前作業系統已經多具備自動更新的功能,甚至企業也可能已經導入了更新的管理工具(如 WSUS),但是更新依舊是一個令人頭痛的問題。因為現在網路服務越來越多樣化,各式各樣的文件、影音格式已經融入日常的應用中,而用來解析這些資料的應用程式(如 Adobe Flash、Adobe PDF Reader、Microsoft Office)就成了有心分子的重要目標。再加上這些應用程式之前不像作業系統那般容易受到攻擊,所以其開發廠商在安全防護的心力與經驗相對較低,進而造成較多的安全漏洞。

針對特定的應用程式,還有一些特定的問題。例如 Flash 的 Plugin 缺乏自動檢查並更新的機制,而且 Flash 的 Plugin 不但不同的瀏覽器需要分開安裝,甚至有些第三方的應用程式也會自行內附 Flash 的動態連結檔 (dll)。所以光要完全更新 Flash 就是一個艱鉅的挑戰。另外一個常見的應用程式 - Java ,則是因為更新時不會自動移除舊版本,所以會造成使用者產生已避免舊版程式問題的假像。

除了應用程式本身造成的安全問題,還有另外一個更需要急迫面對的問題就是部分企業依舊僅將眼光放在作業系統的更新,而忽略了應用程式更新的重要性。這麼多的問題,其結果只有一個,那就是有心分子絕對不會輕易放過這麼好的”機會”。

而在所有攻擊行為中,有 60% 是跟 Web 有關的。其中高達 80% 是利用 SQL Injection 與 Cross-Site Scripting 這兩種手法,再其次則為 PHP File Include。這些”老問題”不但依舊存在,而且甚至有增加的趨勢,顯見企業還沒有認真的面對這些問題,另外一個可能則是還有找到正確的方法。

另外一個觀察到的結果就是所謂的 Zero-day 弱點有增加的趨勢。除了因為有越來越多的應用程式被有心分子當作目標外,另一個更重要的原因在於如何找到軟體漏洞的技能已經越來越”普及”,甚至可以透過一些工具的協助來加快發現的速度。

在資訊安全的領域中,需要定期重新檢討相關政策與風險,並據此擬定計畫。在網際網路發達的這個時代,其所容忍的時間間隔將越來越短,因為有心分子隨時隨地都在找新的機會、新的手法。而在金融風暴的這個時間點,即使沒有面臨資源短缺的問題,至少也會面臨提高效率的議題。所以如何能夠迅速地發現(將)發生的問題,並同時用最有效率的方法加以面對或防範,成了重要的課題。尤其對於資源原本就較欠缺的中小企業,更應該好好檢視對自己最有效益的解決方案,以免發生補了窗戶卻忘了替大門上鎖的糗事。

 

相關連結:

2009年9月15日 星期二

[技術分享] 網頁掛馬攻擊 (Drive-by Downloads) 介紹

雖然有越來越多的廠商與產品試著去解決惡意程式所帶來的問題,但是不可否認惡意程式的威脅與影響依舊越來越大。除此之外,惡意程式也越來越有”創意”,讓這場官兵與強盜之間的遊戲更加精采。儘管惡意程式變化之多,我們仍舊可以將大多數惡意程式的行為(至少)分為兩個階段,第一個階段是感染 (Infection) 階段,第二個階段則是攻擊 (Attack) 階段。

在感染階段中,最重要的事項就是如何避免被發現。在此前提下,其次才是感染的速度與數量。而實際感染的途徑,也從早期的實體方式 (如磁碟片、光碟片等)演進到透過網路的方式。在網路的感染方式中,News Group、Email、IM、Web則陸陸續續被有心人士所利用。今天我們要談的是一種稱之為 Drive-by Downloads 的方式,簡單說來就是讓使用者在瀏覽網頁(或是閱讀HTML格式的信件)時,不知不覺地下載惡意程式並因而遭受感染。也許 Drive-by Downloads 這個名詞對許多人有些陌生,換個說法或許大家就比較清楚,這個說法就是網頁掛馬攻擊。聽起來也許很神奇,但是基本上所謂的”不知不覺”都還是得利用應用程式的漏洞加以遂行。只是跟傳統上利用作業系統漏洞加以感染相比較,現在會被加以利用的則包含了各式各樣的應用程式,尤其是像 Flash 、 PDF 、 影像播放器這類大量被應用在網際網路服務的相關軟體。此外,瀏覽器本身當然也是一個會遭受攻擊的明顯目標。

為什麼 Drive-by Downloads 會漸漸獲得流行呢?在 Drive-by Downloads 之前,Email 附件是主要的感染途徑之一。這些 Email 將惡意程式以附件方式加以夾帶,不但容易被郵件伺服器的防毒軟體偵測到,也會引起教育良好的使用者之疑心而加以忽略。所以,有心分子將腦筋動到了網站瀏覽的行為上。因為網站瀏覽的行為跟收取 Email 有一個本質上的差異,那就是大多網站瀏覽的行為是主動的,而不像收取 Email 是被動的,也因此大多數人在瀏覽網站時不會像收到 Email 一般持有戒心。如果再加上這些瀏覽的網站是”合法”的網站,我相信幾乎沒有人會加以懷疑,事實上也很難加以懷疑。

 

Web 與 IM 成為惡意程式的主要感染途徑

delivery method

Drive-by Downloads有下列幾種做法。首先有心分子可以想辦法先感染所謂的合法網站,然後利用 Drive-by Downloads 的方式讓這些網站的使用者在毫無警戒的情況下受到感染。在網站類型的選擇上,流量越大的網站,像是新聞網站以及 SNS 網站,對有心分子而言越是有利的目標。這種方式漸漸受到有心分子的重視,因為除了防範較為困難外,使用者在使用時幾乎不會有任何的警覺。使用的技巧則可能是 SQL Injection、Cross-Site Scripting (XSS) 等方式,目的就是讓使用者在觀看網站的同時連結或重導向到特定的(惡意)網址以進行感染的動作。而最新的技巧則為利用在合法網站刊登廣告,已達到相同的目的。

除了感染合法網站外,也可以搭配 Email 使用,讓使用者在開啟 Email 的同時連結到特定的(惡意)網址以便進行感染。雖然這個方式可能會引發使用者的戒心,但是對於傳統的防毒軟體(不管是伺服器端或用戶端)而言,要有效地加以偵測仍是力有未逮,也因此效果依舊比附件夾檔的方式來的更為有效些。

而另外一種誘使使用者連到特定網站的技巧就是利用搜尋引擎的結果,如果再搭配 Google Trend 的服務,效果將會更加明顯。在這種方式中,有心分子利用 Google Trend 服務找出熱門的搜尋關鍵字,然後自動產生特定的網站,並且讓這些網站(網址)出現在這些熱門關鍵字的搜尋結果中,以誘使使用者加以點擊並感染之。想當然爾,如何讓這些網站(網址)排在搜尋結果的前面,是有心分子要達成的目標。

一旦電腦被感染後,除了電腦上的資料可能被竊取外,更有可能因為成為僵屍網路的一員而產生危害他人的行為。身為網路的使用者,我們該如何避免遭受 Drive-by Downloads 的攻擊呢?有以下幾點是建議的做法:

  1. 第一法則依舊是維持系統在”最新”的狀態,也就是必須即時的更新。這裡的更新除了指作業系統外,更重要的是必須更新瀏覽器以及相關的外掛 (如 Flash 或 PDF 的 plugin)。因為要不知不覺得感染電腦,扣除設定不良的問題,幾乎還是要利用應用程式的漏洞才能達到目的。事實上,Flash 已經成為目前最容易被攻擊的外掛之一。也因為目前沒有一個機制可以同時更新這些項目,所以我們必須透過一些工具來達到目地,相關工具可以參考我之前的文章
  2. 使用具備偵測/攔阻惡意網址功能的瀏覽器。以目前各種瀏覽器的最新版而言,基本上都具備了這樣的能力,差別只在能力的高低。不過如果你還在使用 IE6 ,很可惜它並不具備這樣的能力。
  3. 使用防火牆、防毒軟體等對抗惡意程式的軟體,而維持這些軟體在最新的狀態,同樣是需要注意的重要事項。畢竟 Drive-by Downloads 雖然可以利用應用程式的漏洞而不知不覺地進行感染,但是感染後安裝/執行的惡意程式碼還是有可能被其他安全軟體偵測出。
  4. 減少使用管理者帳號的時機。對於企業用戶而言,僅開放一般權限給使用者可以大幅減少遭受攻擊後所造成的危害。
  5. 相較於傳統的攻擊手法,小心謹慎對於應付 Drive-by Downloads 的效用將會呈現遞減的現象。因為透過感染合法網站的方式,使用者幾乎是沒有任何加以質疑的機會。所以透過工具將會是比較可行的方式。

對於企業而言,除了上述事項外,還有其他的控制措施可以用來幫助對抗這類攻擊。有興趣的讀者可以參考 Twenty Critical Controls for Effective Cyber Defense: Consensus Audit Guidelines 這份文件。

 

相關連結:

2009年9月9日 星期三

[個人意見] 問題的問題 (四之四)

既然是資安的論壇,我們在這系列的最後一篇文章中就來看看資怎麼下手解決複雜的資安問題。我會用一個假想的例子來加以說明。

假設今天有一個抽獎系統,原本的設計是在每次抽獎時會從所有會員中隨機抽出特定數目的會員致贈出豪華獎品。因為每次抽獎的獎品數量、種類都不盡相同,所以順帶提供了一個後台介面讓有權限的人可以設定獎品的數量、種類、以及抽獎的時間。在一次的抽獎結果中,事後卻意外發現頭獎(百萬獎金)的中獎人與該系統的系統管理員竟是一家人,而此系統管理員已於此次抽獎後的隔天無故離職,而得獎者也已經把獎金領走了。進一步的追蹤發現,此系統管理員到職僅約半年的時間,而且之前的工作經驗都在別的地區。

為了追蹤問題發生的原因,我們必須先找到為何得獎者”剛好”是該系統管理員的家人。是抽獎程式被修改而未被發現,還是抽獎程式執行時被其他程式干擾而產生異常的結果,還是在公布結果前得獎者的資料被置換了,甚至有可能是公布後原先得獎者的個人會員資料被換掉了。經由我們的分析發現,原來是因為程式被修改而未被發現,所以抽獎程式在該次抽獎中”一定”會抽中特定的會員(原系統管理者的家人)。

這次事件發生的"直接”原因被發現後,我們可能的立即反應就是如何避免抽獎程式執行異常(如抽出特定的會員)的行為。但是如果這樣就開始要找解法稍嫌過早了。首先,抽獎程式被修改而未被發現,至少還可以衍生出員工素質不良、程式碼管控不當、沒有做好程式的完整性檢查、CM機制不足等更深層的原因。除了這些原因外,因為系統本身還有其它的管道可供有心份子做手腳,所以如果不一併加以考慮,就算今天補了第一個缺口,其他缺口依舊存在。這也是我在第一篇文章中提到有關解決問題的第四個階段 ─ 避免類似問題再發生。這個階段(避免類似問題再發生)對於資安議題特別重要,原因在於資安問題不像一般資訊系統,就算再小心問題還是會”主動”發生。如果沒有抱持未雨綢繆的心態來加以面對,恐怕不只是疲於應付問題,我想應該是連飯碗都不保才是。

事實上,我們認真的看待所有的可能性後,發現都有一個共通的原因,那就是素質不良的員工。為了因應這個問題,包含員工背景調查、責任劃分(Separation of duty)、Two-man control、定期輪調等管理措施或許是更有效的防範方法。對於程式碼管控,則有責任劃分、權限管控等機制可以運作。

當然我們不能這麼武斷,必須經過一些分析的方法找出真正值得執行的解法。而光是避免程式被修改這個議題,就可能衍生出許多種可行的解決方法。那麼當再加上其他議題後,解決方法沒有上百,也有數十個。如果這樣討論下去,整個需要比較的資料會過於龐大,所以在資訊安全的領域中,會透過風險分析的方式,試圖將分析步驟作簡化的動作。風險分析的方法,基本上就是把所有原因(稱之為威脅)的發生機率跟危害程度做一個分析,兩個數值相乘後的值就是該威脅造成損失的期望值,然後將期望值較高的威脅(原因)當作解決的對象[註一]。除了適用於上述的定量化分析方法外,定性化分析方法也可以應用同樣的概念。對象決定後,再找出針對各個威脅(原因)最有效率的解法。也就是說,透過風險分析將找尋最佳解法的步驟一分為二,避免了因為威脅(原因)與解法之間的交互作用所產生的複雜情況。嚴格來說,這樣的做法不見得能夠找到真正最有效益的解法,但是在面對資訊安全這麼複雜的議題時,卻是一個比較可行的方法。更何況資訊安全有時候不能僅從效率的角度來看,當風險很高時,就算是要花多一點的錢,也有不得不為的時候。就用我們買保險一樣,不見得都是買最划算的保險,有些保險買了是求心安的,有些則是避免發生問題時只能等死。

事實上,風險分析的方法在很多地方都有用到,像是金融財務、以及這幾年大行其道的專案管理都有這樣的做法。 只是在不同的領域中,因為對損失的定義不同,所以考慮的對象會有所差別。儘管如此,基本的精神都是一樣的,就是先找出會造成最大損失的點加以面對並處理之。

如何有效地處理問題,在此次金融風暴發生後的此刻更形重要。因為,省錢如果只是省錢,其實沒有大太的幫助。如果能夠省錢但是依舊完成同樣的任務,甚至能夠完成更多的任務,如此一來才能大幅增加企業的競爭力。當然,這個議題踩到另外一個大多數公司的痛腳,那就是哪些事情對公司而言才是有價值且重要的業務。道理很簡單,把風險分析反過來用就可以了(其實還有更適合的方法),但是這通常已經是非常非邏輯性的問題。怎麼解,就得靠各位的科學與藝術天分了。

註一:計算單一威脅損失期望值的公式為

Annualized Loss Expectancy (年度損失期望值) =
    Asset Value (資訊資產的價值) *
    Exposure Factor (此威脅造成事件發生會造成多少比例的損失) *
    Annulaized Rate of Occurrence (每年度此威脅造成危害的次數)

2009年9月8日 星期二

[個人意見] 問題的問題 (四之三)

在理想的世界中,我們只要想辦法找出最有效率的解法就天下太平了。但是在現實的環境中,除非問題本身很單純(不一定是簡單),否則真正”問題”才剛開始。最大的可能性在於,邏輯性的問題變成了非邏輯性的問題,而背後的因素幾乎都跟”人”有關。

舉例來說,如果你是一個工程師,正在解決電腦主機板所造成的當機問題。經過一番努力後,你發現原來是主機板上的音效晶片在播放特定訊號時,會因為處理不當而造成當機。而且你也已經證明是晶片本身設計的問題,而不是主機板設計或相關軟體的問題。更糟的是,這種錯誤沒有辦法經由主機板或軟體的修改加以修正。正常來說,除非修改主機板的功能,否則唯一的(最佳)解法就是換一組晶片。但是很不幸的是此一音效晶片的上游廠商,是公司很重要的夥伴。所以要不要換,能不能換,已經不是單純技術性(邏輯性)的問題,而是政治性(非邏輯性)的問題。相關團體彼此之間的利害關係,成了左右問題解決方案的重要因素。

另外一個可能的因素就是時間因素。幾乎所有的問題都有其時效性,如果解法所需花費的時間大於該問題的時效性,那麼是否需要執行就有很大的思考空間。尤其是當外界對於解決問題充滿了急迫性的期待時, Quick Fix 往往就成了優先執行的項目,甚至有時候得做出一些沒有效果的”假動作”以杜悠悠之口。雖說是時間因素,但是時間的急迫與否同樣是以”人”的觀點才有意義。

除此之外,如果問題的解決方法涵蓋廣泛的範圍(如跨越多個不同的部門)時,為了減少初期遭遇的阻力,我們需要採用縮小範圍的解決方案。待達到一定的效果後,才做更全面的問題解決。縮小範圍的另外一個好處是,投入的資源相對較少,因此較容易獲得相關人士(尤其是CEO/CFO)的首肯。

不過不管採用的方法為何,都應該訂定出最終的目標,例如是要徹底解決問題還是掩蓋問題(這也算是某種程度的解決問題)。這樣不管是將解法分成幾個步驟,甚至是出現假動作,都能繼續朝最終的目標前進,完成解決問題的目的。以前一篇文章的例子而言,最終目標是修正軟體就好,還是要改進品質管控的能力,必須先加以釐清以利後續作業。

所以,我個人認為解決問題本身是一門科學,同時也是一門藝術。只是在解決邏輯性的問題是純粹的科學,而面對非邏輯性的問題時,除了科學更需要一些藝術。至於用藝術來處理邏輯性的問題(或非邏輯性問題中邏輯的部分),只能叫做瞎攪和,而不是藝術。也因此解決問題往往沒有甚麼公式可以套用,更沒有所謂的標準解法。所以,我講了這麼大篇幅的目的是甚麼?我認為真正重要的是公司要建立起自己解決問題的文化,這樣員工在解決問題時才不會出現”不相容”的情形。假設公司的文化就是得過且過,此時如果有一個實事求事的人想要解決工作上的問題,我想十之八九這位員工會過得很痛苦。所以差的不是用”濫”解法來解決問題的公司,而是沒有明顯的文化,甚至是說一套、做一套的公司。這樣的公司會產生一堆無所適從的員工,最好大家只好等著公司的指令才能見招拆招,何必呢?

在這系列的最後一篇文章中,我們來看看在資訊安全領域中我們應該如何下手處理錯綜複雜的資安問題。

2009年9月7日 星期一

[個人意見] 問題的問題 (四之二)

在前一篇文章中,我們看到解決一個問題的基本做法。但是有一個必須注意的事項就是,通常原因背後還有其發生的原因,或者換個角度說問題後面還有問題(QBQ - Question behind Question)。所以我們必須發現的可能不是一個原因,而是一堆(可參考 Root Cause Analysis)或一連串的原因(可參考 Fault Tree Analysis)。既然如此,我們怎麼知道是不是該往下繼續找出原因背後的原因呢?除非發生問題的事物有明確的邊界,否則這個問題並沒有很明確的分界點,往往得靠自己的直覺加以判斷。不過,基本的準則是至少要把原因分析到你無法掌握或改變的事項。至於解決方法是不是一定要斬草除根呢?我認為倒是不一定,理由後述。

再以程式開發為例。當我們發現交付給客戶的產品 (軟體)有一個程式寫作的錯誤時,除了修改程式外,我們更可以(應該)分析為何這樣的錯誤沒有在交付客戶之前就被發現。所以問題變成了品管的問題,甚至是品質保證、流程管控等議題。這些議題涵蓋範圍之廣,已經足以影響整個工作的流程,而不僅僅是修改程式那麼單純。

當我們找到的是一堆原因時,問題就變得相當複雜。要解決最接近問題的原因、最根本的原因,抑或是有其他的選擇呢?我們都知道從最根本的原因下手,通常可以達到最好的效果,正是所謂的斬草除根。比較好的作法,往往還是從效率的角度來看,只是這時候除了必須評估所需資源與效果之外,也必須考慮到解法本身與原因的交互關係。原因很簡單,有時候一個解法可以同時解決多項原因。

舉個簡單的例子來看,假設有個問題經過分析後,共有四個原因,其關係如下:

cause 

這針對這些原因,我們知道有5種解法,其效率分別如下:

cause2

如果以成本效益的角度來看,成本最高的解法(解法3)反而成了最佳的選擇。

會有這麼複雜的規則是因為一個表面呈現出來的問題,可能代表了背後有數個問題的存在,而這數個問題又有各自不同的解決方法。彼此之間錯綜的關係,造成了我們在評估最有效益的解決方案時的複雜度。所以資訊安全領域採用另外一種做法(稱之為風險分析,也應用在其他領域),可以避免這樣的複雜度。不過在討論風險分析的概念前,我們在下一篇的文章中先看看為什麼邏輯性的問題會演變成非邏輯性的問題。

About