Authentication 的資訊安全設計原則、測試、個案與實作
這篇文章主要討論 Authentication 認證的資訊安全議題,涵蓋下列主題:
- 認證的資訊安全設計原則,
- 針對認證測試可以用的工具與測試方法作討論
- 認證所導致資訊安全事件的實際新聞與個案討論,
- 最後舉一個程式碼範例說明好的設計與不好的設計差異。
認證基本原則
認證不外乎是運用下列三個的組合。
- 知道:例如知道帳號密碼
- 擁有:例如擁有手機或是實體的憑證
- 誰:生物辨識。像是指紋或是視網膜
認證的安全設計基本原則為
- 定義密碼規則
- 登入錯誤失敗時的鎖定(Lock-out)機制
- 忘記密碼的處理流程
- 禁止使用 Http或是 HTTP Get來處理密碼
定義密碼規則
怎樣的密碼規則才是相對安全呢? 舉例如下:
- 最低密碼長度的限制。例如最少8個字元
- 強制文字與數字的組合
- 不允許包含使用者名稱
- 使用者可以或是定期更改密碼
- 密碼的有效期限並建議使用者更換密碼
- 避免之前使用過的密碼重複使用
實際案例新聞 Twitter
http://www.wired.com/2009/01/professed-twitt/
2009年 Twitter 就曾經因為Twitter的帳號可以無限制的嘗試登入,加上密碼的規則過於簡單,例如 “happiness”。
因此有 18歲的高中生,很快的就知道許多別人的密碼。會導致這樣的事件發生,主要的安全設計漏洞遺漏了下列規則:
- 最低密碼長度的限制。例如最少8個字元
- 登入錯誤失敗時的鎖定(Lock-out)機制
- 強制文字與數字的組合
當然這樣的事件層出不窮,
http://betanews.com/2014/09/30/weak-passwords-are-still-a-major-problem-for-business-security
雖然密碼符合最少八個字元與文字與數字的組合。但是看看這些密碼: “Password1”, “Hello123”, “password”
還是讓駭客有機可乘。那麼到底怎樣的密碼組合規則是比較建議的呢?
- 最低八個字元
- 密碼的組合至少包含下列三種 (大寫 + 小寫 + 數字 + 符號)
- 密碼不可以包含使用者名稱
- 密碼的有效期限為六個月
- 密碼最少有效期限為一天 (避免駭客透過短時間內創造大量的帳號與修改密碼,間接得知認證的機制)
登入錯誤失敗時的鎖定(Lock-out)機制
上述提到 Twitter的例子就是因為沒有 Lockout 的機制,讓駭客可以無限制的嘗試帳號密碼導致資訊安全風險。
駭客可以用哪些工具呢? 常見的攻擊方法為 Brute Force vs. Dictionary Attack
筆者舉一個例子 Hydra,這個工具只要提供密碼的字典,就會自動不斷的嘗試登入並且告知成功登入的結果。
Hydra工具:http://www.thc.org/thc-hydra/
密碼字典檔案:https://code.google.com/p/fuzzdb/source/browse/#svn%2Ftrunk%2Fwordlists-user-passwd%2Fpasswds
程式範例(風險極高)
這段處理帳號登入的風險極高。為什麼呢?
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
1 int validateUser (char *host, int port)
2 {
3 int isValidUser = 0;
4
5 char username[USERNAME_SIZE];
6 char password[PASSWORD_SIZE];
7
8 while (isValidUser == 0)
9 {
10 if (getUserInput(username,USERNAME_SIZE) == 0) error();
11 if (getUserInput(password,PASSWORD_SIZE) == 0) error();
12
13 isValidUser = AuthenticateUser (username, password);
14 }
15
16 return(SUCCESS);
17 }
[/pastacode]
主要原因在於沒有 Lockout的機制。因此駭客可以無限制的嘗試登入。
因此,在驗證該使用者輸入帳號密碼前,應該要先確定輸入帳號密碼的次數,
如果次數超過指定的範圍,那麼就不應該繼續驗證該密碼。
相關實例
Yahoo 拍賣 ID 的實例 http://www.ithome.com.tw/node/44923
“劫標信詐騙,是歹徒於網拍賣場擷取買家帳號,並冒充賣家寄信給買家,利用買家貪小便宜的心理,要求提前匯款,藉此達到騙取匯款的目的。”
另外一個真實的資安事件,有人利用 forgot password 的相關 Security Questions (例如:生日、寵物、郵遞區號)
間接盜取其他人的帳號。https://en.wikipedia.org/wiki/Sarah_Palin_email_hack
另外,Apple也曾經被發現在密碼重設時,只要簡單的電子信箱與生日就可以重設密碼。
因此對於這些密碼重新設定有沒有什麼建議的安全設計方式呢?
要求使用者取很複雜的 Security Questions 是很難的。因為太複雜使用者自己也記不住。所以可行的方式如下:
- 系統只會寄發新的密碼重新設定通知道原始註冊的信箱。
- 系統會重新寄發新的一組密碼或是給一組連結直接讓使用者可以重新更換密碼。而不是將原本的密碼寄出。
- 限制密碼重設的周期與次數。這點主要擔心駭客利用密碼 lockout 或是重設的機制癱瘓該帳號使用。
密碼用明文或是HTTP GET 傳送
如果是 Web service 就必須要用 HTTPS 加密傳送,並且透過 Http Post 的方式。
GET 傳送密碼的話,帳號密碼就會出現在 URL 中。儘管傳輸為 HTTPS密碼還是一樣明文傳送
https://www.sample.com/?Action=login&user=sam&password=1234
另外,一般密碼的儲存建議都是以 Hash的方式儲存。而非以明文的方式儲存。
如此一來就算密碼檔案被偷走,沒有適當的密碼演算法也沒有用。
但是國內還是有許多的線上服務廠商密碼是明文儲存。
我的密碼沒加密 http://plainpass.com/
網路監聽測試工具
一般的網路監聽測試工具都可以攔截到這樣的訊息。如果密碼為明文傳送,那麼密碼在網路上流傳就很危險。
- http://www.nirsoft.net/utils/password_sniffer.html
- WireSharkin
- Fiddler
認證基本安全原則
關於認證四個基本安全設計原則:
- 定義密碼規則
- 登入錯誤失敗時的鎖定(Lock-out)機制
- 忘記密碼的處理流程
- 禁止使用 Http或是 HTTP Get來處理密碼