標籤:清單 string integer control 開發人員 where 資料庫 resultset 使用者
繼續對Fortify的漏洞進行總結,本篇主要針對 Access Control: Database(資料越權)的漏洞進行總結,如下:
1、Access Control: Database(資料越權) 1.1、產生原因:
Database access control 錯誤在以下情況下發生:
1. 資料從一個不可信賴的資料來源進入程式。
2. 這個資料用來指定 SQL 查詢中主鍵的值。
樣本 1:以下代碼使用可轉義元字元並防止出現 SQL 注入漏洞的參數化語句,以構建和執行用於搜尋與指定標識符相匹配的清單的 SQL 查詢。您可以從與當前被授權使用者有關的所有清單中選擇這些標識符。
...
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 值。雖然介面產生了一個目前使用者的標識符清單,但是攻擊者可以繞過這個介面,從而擷取所需的任何清單。因為此例中的代碼沒有執行檢查,確保使用者有權訪問需要的清單,所以代碼會顯示所有清單,即使這些清單並不屬於目前使用者。
1.2、修複方案:
與其靠展示層來限制使用者輸入的值,還不如在應用程式和資料庫層上進行 access control。任何情況下都不允許使用者在沒有取得相應許可權的情況下擷取或修改資料庫中的記錄。每個涉及資料庫的查詢都必須遵守這個原則,這可以通過把當前被授權的使用者名稱作為查詢語句的一部分來實現。
例:以下代碼實施了與例 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();
總之,要防止資料越權的漏洞問題,需要做到以下兩個要點:
a、對需要查詢的資料,給sql語句加上資料許可權的限定條件,限定資料所屬角色。
b、對於這個加上的資料許可權的限定條件,最好是從後台擷取,而不是通過前台傳入。
Fortify漏洞之Access Control: Database(資料越權)