2014年1月8日 星期三

儲存 Password 安全性

Password

        Password 是大部份系統用來認證或是識別使用者最常見的方式,特別是網站系統最需要這種機制,來提供一般使用者進行登入取得瀏覽的權限或是使用網站的服務。網站系統最常見的保護方式就是在網頁上提供隨機的圖形驗證碼 CAPTCHA ,來避免有心人透過工具作自動化的方式暴力破解使用者的密碼。然而,一個系統的安全性取決於系統環節中最弱的一環。因此,擋得住網站系統前端,卻擋不住系統後端資料庫時,一旦被攻破資料庫時,若使用者的密碼沒有被保護而以明文(Plain-Text)的方式儲存時,這樣的系統可以說是完全沒有任何安全性。因此,比較有良心的開發人員,會透過其他方式來保護使用的密碼。

早期 Password 的保護方式

        早期對於Password的保護方式是透過 password + salt 方式,把這兩個值當作參數進行 Hash 運算(MD5, SHA1,SHA256...etc),每一個 password 都需要搭配一個隨機產生的 salt,並且透過 One-way 的 Hash 函數算出一個亂數值的字串來存放。所謂的 One-way 的 Hash 函數是指無法透過知道 salt 和產生後的亂數值算出原本的 password。對於這方面的技術有興趣的可以參考 Slated Password Hashing 的文章。在過去硬體的運算能力不夠快的情況下,這樣的保護機制其實是足夠的。然而運算能力越來越強的情況下,這種保護機制隨即崩盤,請參考2012年Speed Hashing 的文章,裡面主要是提到GPU運算能力可以很容易的破解 SHA1+Salt 所保護的密碼。

建議的 Password 的保護方式

        目前(2013)在密碼學領域建議用來保護密碼的 key derivation function 我目前知道的有以下這幾種: scrypt, bcrypt, PBKDF2. 之前的專案曾經用Python版本的 bcrypt 來做 Password Protection的處理.

Reference

Using scrypt in Python and PostgreSQL - http://kevinryan.me/using-scrypt-in-python-and-postgresql/


Threat Modeling


        Threat Modeling 是在系統設計階段的早期, 以 Data Flow Diagram 為基礎, 來對整個系統設計做安全性威脅的分析. 而這個過程是一個重複的過程, 透過重複分析安全性的威脅, 並且提出相對應的解決方式,並且解加以驗證是否解決或是降低威脅性.

        然而, 它不僅只是在設計階段, 當系統增加功能或是改變原有的功能時, 也可以利用它來分析系統的變動是否出現安全性的威脅.



為了做 Threat modeling 的分析, 我們必須先將系統的 Data Flow Diagram 畫出來. 這個可以藉由微軟所提供的工具 SDL Threat Modeling Tool 來完成 Data Flow Diagram 以及後續的分析.

Data Flow Diagram (DFD)

        基本上 Data Flow Diagram 可以根據不同情況來畫出對應的 DFD. 並且依據每個DFD來進行分析. Data Flow Diagram 主要有 5 個 Elements 如下:
  • Process
    以 High Level 的角度來看時, 它可以是Web Services或是在作業系統上的一個Service. 以 Detail Level 的角度上來看可以是一個DLLs或是一個EXEs的執行檔.
  • Data Store
    通常指的是存放資料的地方, 常見的有資料庫,檔案或是Shared Memory甚至是Queue或Stack.
  • External Entity
    通常指的是會與你的系統互動的使用者或是外部的 Systems 或 Services.
  • Data Flow
    就是指以上 3 種 Elements: Process,External Entity以及 Data Store之間溝通的資料流.
  • Trust Boundary
    是指不容易受到外部影響或是干涉內部運作的一個範圍的分界. 例如: 都在同一個Private Data Center 內部之間的Server溝通. 例如: 透過網路溝通的兩個 processes 通常會有一個 trust boundary 在它們之間, 即使他透過安全的通訊方式也是如此. 


        而畫 Data Flow Diagram 最重要的一個是畫出 Trust Boundary, 它主要的目的是用來判斷哪些 Data Flow的運作是具有安全性威脅.  舉例來說: 一個 Process 內部的 Thread 通常都算是 Trust Boundary 內的, 原因是 Thread 所擁有的權限都是由 Process 所提供且共享的. 常見的 Trust Boundary 例子有 Machine boundaries, privilege boundary, integrity boundary ...等等這些.
       
        此外, 我們也應該要檢視每一個 Processes 和 Data Stores 是否需要再進一步畫出更詳細的 DFD. 所以 DFD 通常又可以分為以下四種, 但是很少需要畫到 Leve 3, 大多只需要畫到 Level 2 就已經可以.

  • Context Diagram
    非常 high-level 完整的 component 或是 product, system 之間的互動
  • Level 1 Diagram
    High level 但是只針對某一個單一的功能或是情況的互動
  • Level 2 Diagram
    多個功能中需要用到的 sub-component 比較詳細的部份
  • Level 3 Diagram
    更為詳細部分

        最後, DFD 應該詳細條列出對應的假設或是相依性的關係. 一開始可以先以 High Level 的方式畫出 DFD, 之後可根據是否需要更詳細的解釋說明安全性在設計上的影響, 或是需要資料通過 trust boundary 的細節...etc. 來決定是否畫出更詳細的 Level 1 ~ Level 3 的 DFD.

        畫 DFD 時候, 需要透過以下幾個問題來驗證你的 DFD 能夠拿來做 threat modeling 分析.
  • Data 如何產生? 來自於 external entities 還是來自於 data stores
  • Data 用在什麼地方? 誰會使用它? 儲存這些資料的理由?
  • Data 如何在不同的 Process 中傳遞.
  • Data 被哪些 Process從 Data Store 存取

Identify Threats

        如果有安全性的專家參予其中分析是最好的, 如果沒有的話,可以透過 STRIDE 的步驟來檢視 DFD 中的每個 element. STRIDE 就是指以下這些:
  • Spoofing 偽造
    例如: 申請類似的網址,偽裝某個知名的網站
  • Tampering 竄改
    例如: 修改軟體所需要的DLL植入惡意程式,或是竄改封包的內容
  • Repudiation 否認
    例如: 否認發送過某個 Email, 或拒絕承認瀏覽過某個網站
  • Information Disclosure 資訊外洩
    例如: 無論是惡意或是無意, 將重要的客戶資料流出, 讓未經授權的人使用.
  • Denial of Service 中斷服務
    例如: 系統無法運作, 或是網站無法服務
  • Elevation of Privilege 提高權限
    例如: 讓一個遠端一般使用者,透過非正常的管道,提升權限能夠執行一些只有系統管理員才能使用的指令集.
        對於DTD中的每一個Element而言, 都有個別需要注意的威脅如下圖: