API 安全問題探討

2017/09/09

Web 2.0興起10個年頭,AJAX應用程式快速成長,與其配合的後端語言也隨之蓬勃發展。另外在行動裝置推波助瀾的情況下,各種APP應用程式大量出現,呈現方式與傳統Web相比更具彈性,更多資源放置在用戶端,程式反應更快、使用者體驗更好。開發人員亦大量開發API (Application Programming Interface) 應用在市場上蓬勃發展的行動裝置APP,但這樣的轉換是否會帶來新的風險?

API基於 HTTP 通訊協定之上,所以在身分驗證的特性與一般網頁相同,也就是所謂的「無狀態」(Stateless),也就是每一次的連線都是唯一、獨立的,沒有維持(retain)連線的狀態的意思。使用Cookie、WWW-Authenticate、Authorization表頭處理認證問題。

而功能實作方面,如以一般開源的程式語言遵循Rest API 開發,可以直觀的以HTTP Method 加上URI,帶上以JSON封裝的資料,抽象而直觀的表達,以POST或是PUT代表Create、GET表達Read、PUT表示Update、DELETE等於Delete四個動作。在微軟的.Net Framework中的Web API則以GET和POST對API操作。

. 使用Node.js中常用的身分驗證middleware套件 " passport ",讓我們來看官網中身分驗證教學範例的程式碼:

我們可以看到基本的身分驗證判斷流程如下

在這裡犯了實作Authentication中很常見的錯誤:不正確的錯誤訊息回應。由OWASP的Authentication Cheat Sheet中的Authentication and Error Message(https://www.owasp.org/index.php/Authentication_Cheat_Sheet#Incorrect_Response_Examples)可以得知過於詳細的錯誤訊息回應可以讓攻擊者得知部分資訊,可以直接猜測程式流程,進一步做後續的攻擊動作。
以上圖來看,當錯誤訊息回應"帳號錯誤"時,可以得知檢查帳號的環節出錯,也就是輸入的帳號並不在資料庫內。若利用程式撰寫大量對伺服器發送封包的腳本程式,將可得知資料庫裡的使用者帳號,也就是所謂的帳號列舉問題。
所以這部分的程式碼邏輯應該被修改為這樣,將帳號或密碼輸入錯誤的問題做一次判斷並輸出:

當然,開發網站的你可能會認為帳號被猜出來沒什麼大不了,但是現今駭客手中都有所謂的"社工庫",也就是社交工程資料庫,駭客從攻擊中所獲取的資料庫、或是從暗網黑市中所購買的資料庫,經過破解雜湊值後,整理出自己的一套帳號密碼資料庫。若駭客得知使用者的帳號後,可從手中的社工庫中找尋該使用者習慣使用的密碼,嘗試登入該網路服務。

此類問題於API問題中常出現,因API於開發的設計架構上較偏好在回應訊息的詳細程度上做詳細的敘述,並直接將訊息回應至使用者前端,讓整體使用者體驗更好、讓使用者覺得方便,但安全總是與方便牴觸的,在這方面還是不得不注意一些小細節上的問題!

這部分也是絕大多數討論API安全問題時,一定會提到的問題,我們先來看一段express.js官網中的範例程式碼:

express 中提供了一個相當方便的回傳方法,針對 response 物件可以直接引用 JSON 函式將資料回傳。
另外,我們設計一個使用者資料的schema如下:

express 中提供了一個相當方便的回傳方法,針對 response 物件可以直接引用 JSON 函式將資料回傳。
我們現在將情境限縮在針對使用者資料讀寫的情況下做探討。
一般遇到需要回傳資料的情況下,開發者可以很直觀的將物件直接以物件回傳至前端,就算多傳了資料,對於前端運作並無影響。
但是在此情境下,如果將整個gary回傳至前端,也就是將整個使用者資料全部、連帶前端不必顯示的資料一並回傳,在這種情況下,雖然前端用不到但是駭客全部都用的到呢!
在現今要求開發速度快速、開發者時間不夠的情形下,如果開發者不小心,在沒有確認資料內容的情況下,直接將整個使用者資料物件回傳,若是遇到有心人士,將造成使用者個資大量外洩之問題!

此類情形在許多的APP或是前後端分離的網站中,若存在查詢其他使用者的功能中經常出現。是開發者不得不注意的課題!

除了使用者個資上的問題,在實際的滲透測試專案中,也曾經出現簡訊的二階段認證功能,於資料傳輸過程中將認證碼外洩的問題,也是開發者未確認物件資料內容就將功能撰寫完畢的案例。


其他訊息