Fortify Audit Workbench 筆記 Access Control: Database

  • 2020 年 3 月 14 日
  • 筆記

Abstract

如果沒有適當的 access control,就會執行一個包含用戶控制主鍵的 SQL 指令,從而允許攻擊者訪問未經授權的記錄。

Explanation

Database access control 錯誤在以下情況下發生:

  1. 數據從一個不可信賴的數據源進入程式。
  2. 這個數據用來指定 SQL 查詢中主鍵的值。 例 1: 以下程式碼用到一個參數化指令,這個指令轉義了元字元,以防止SQL injection 漏洞,並構建和執行一個 SQL 查詢。該 SQL 查詢指令可以搜索與指定標識符 [1] 相匹配的清單。 您可以從與當前被授權用戶有關的所有清單中選擇這些標識符。
...  id = Integer.decode(request.getParameter("invoiceID"));  String query = "SELECT * FROM invoices WHERE id = ?";  PreparedStatement stmt = conn.prepareStatement(query);  stmt.setInt(1, id);  ResultSet results = stmt.execute();  ...

問題在於開發者沒有考慮到所有可能出現的 id 值。 雖然介面生成了一個當前用戶的標識符清單,但是攻擊者可以繞過這個介面,從而獲取所需的任何清單。 因為此例中的程式碼沒有執行檢查以確保用戶有權訪問需要的清單,所以程式碼會顯示所有清單,即使這些清單並不屬於當前用戶。 許多現代 Web 框架都提供對用戶輸入執行驗證的機制。 其中包括 Struts 和 Struts 2。 為了突出顯示未經驗證的輸入源,該規則包會對 HPFortify Static Code Analyzer( HP Fortify 靜態程式碼分析器)報告的問題動態地重新調整優先順序,具體方法是在採用框架驗證機制時降低這些問題被利用的可能性並提供相應的依據。 我們將這種功能稱之為上下文敏感排序。 為了進一步幫助 HP Fortify 用戶執行審計過程, Fortify 安全研究團隊開發了 Data Validation(數據驗證) 項目模板,該模板根據應用於輸入源的驗證機制按文件夾對問題進行了分組。

Recommendation

與其靠表示層來限制用戶輸入的值,還不如在應用程式和資料庫層上進行 access control。 任何情況下都不允許用戶在沒有取得相應許可權的情況下獲取或修改資料庫中的記錄。 每個涉及資料庫的查詢都必須遵守這個原則,這可以通過把當前被授權的用戶名作為查詢語句的一部分來實現。 例 2: 以下程式碼實施了與例 1 相同的功能,但是附加了一個限制,即為當前被授權的用戶指定某一特定的獲取清單的方式。

...  userName = ctx.getAuthenticatedUserName();  id = Integer.decode(request.getParameter("invoiceID"));  String query =  "SELECT * FROM invoices WHERE id = ? AND user = ?";  PreparedStatement stmt = conn.prepareStatement(query);  stmt.setInt(1, id);  stmt.setString(2, userName);  ResultSet results = stmt.execute();  ...