SQL Injection
SQL Injection 蟬聯 OWASP TOP 10 冠軍寶座從2013年版到最新的2017年版,可見其造成的傷害及普遍性之高,畢竟開發人員在將外部參數丟入 SQL 命令列時,為了方便就直接帶入,省略了過濾或用參數化的方式,相信有寫過串接 Database 的網站開發人員都會有的經驗。
SQL Injection 為透過外部使用者的輸入或可供改造的參數,未經驗證就帶入 SQL 相關指令被執行,導致跳脫原先預期的行為,變成攻擊者想要的行為。攻擊行為可利用 SQL 的指令如 SELECT、UPDATE 或 DELETE 等來造成資料庫非預期的行為,若執行權限又沒特別去做區分,等於將整個資料庫被外部任意存取與動作,甚至可用來執行指令碼,後果將難以彌補!
SQL Injection 攻擊型態類型
- CAPEC-7:盲目的SQL注入
- CAPEC-66:SQL注入
- CAPEC-108:通過SQL注入執行命令行
- CAPEC-109:對象關係映射注入
- CAPEC-110:通過SOAP參數篡改進行SQL注入
- CAPEC-470:從數據庫擴展對操作系統的控制
綜合這幾種類型,可以得知為防範此攻擊,為當外部參數進入SQL 陳述式(Statement)前,需再經過驗證格式是否合法,是否有隱藏特殊符號等檢查,主要有以下幾種方法:
參數化
將參數經過 Parameter 或 Prepare 等可用來對 SQL 參數做執行前的型態轉換,若有特殊字元將無法產生攻擊作用,最為推薦此種方法!
.NET
String query = “SELECT account_balance FROM user_data WHERE user_name = “
+ request.getParameter(“customerName”);
try {
Statement statement = connection.createStatement( … );
ResultSet results = statement.executeQuery( query );
}
PHP
$preparedStatement = $db->prepare(‘INSERT INTO table (column) VALUES (:column)’); $preparedStatement->execute(array(‘column’ => $unsafeValue));
替代字元
使用 Replace() 等方法來將特定字元做替換,但可能攻擊字元稍微經過變化或加密後,變成誤擋或漏檔等結果。
string sql = “SELECT * FROM WIDGETS WHERE ID=” +badValue.Replace(“‘”,”””);
正則表達式
利用 Regular Expression 設定合法的格式,直接用白名單方式限定參數的內容,這就變成需根據資料的不同來調整對應的 Regex,雖然嚴謹但較為麻煩,但有可能產生誤擋或漏擋的情況發生。
以上幾種防範方法適用於 Injection attack 類型的攻擊行為,可針對外部不被信任的參數做驗證與過濾處理,避免產生不可預期的行為,可視資料的多樣性與參數用途來選擇相對應的防禦方式。