前陣子在開發電子發票搜尋篩選功能時,意外發現自己用字串串起篩選文字的方式可能會引發SQL注入攻擊,閱讀一些資料後發現,至今SQL注入攻擊仍是非常常見的駭客攻擊手法,因此在今天的篇章中我們將介紹甚麼是SQL注入攻擊以及幾種避免發生的方法。
一. 什麼是SQL注入
SQL注入攻擊是Web開發中最常見的一種安全漏洞,利用沒有過濾過的用戶輸入,來從資料庫獲取敏感資訊,或者利用資料庫的特性執行添加用戶,導出文件等一系列惡意操作,甚至有可能獲取資料庫乃至系統用戶最高權限。
實例:
大多查詢的程式碼都是以字串的方式串起(如紅框框所示),如果在畫面上的密碼部分,輸入‘ OR 1=1; — ,因為1=1恆等式一定會成立,且condition為OR,所以可以把前面的WHERE condition都忽略掉。後面再補上個分號以及–將後面的指令碼註解,透過這種方式網站資料就形同沒有任何防護,資料就任意被讀取甚至刪除。
二. 如何避免
前端
1.驗證輸入格式
最直觀最直接的方法,檢查輸入的資料是否具有所期望的資料格式,嚴格限制變量的類型,例如使用正規表達式(RegExp)進行一些匹配處理。
2.避免讓使用者看到詳細的錯誤訊息
假設程式未對參數做檢查,導致資料庫存取的執行錯誤如下圖:
由此錯誤訊息中,使用者可以獲取許多情報:
1. 程式使用「ODBC」方式連上「SQL Server」。
2. 程式透過共用的ASP程式(Connect.asp)連結資料庫。
3. 程式直接將UserId接在SQL指令中,且沒有外括單引號。
接下來只要猜想密碼欄位大概的名稱,修改URL為UserInfo.asp?UserId=1+AND+Password=1
SQL的組成也就會變成如下:
SELECT … FROM UserInfoTableName WHERE UserId=1 AND Password=1
由於故意夾帶錯誤且SQL SERVER會提供自動轉換的功能,讓密碼欄位名稱顯示於錯誤訊息中如下:
循著這個漏洞可以進一步尋覽所有會員編號來獲取密碼,因此在正式上線後,最好善用IIS設定客製化錯誤訊息或ASP.NET web.config中CustomError設定,對一般使用者隱藏錯誤的細節資訊。
後端
1.改用Parameter方式傳入動態參數
透過使用Parameter在SqlCommand執行時會自動過濾掉可能造成問題的字元。
另外只要是畫面上可能被改變的值,就應使用Parameter,因為SQL Injection不只會發生在WHERE condition,包括了Url上的QueryString,POST過來的表單資料,甚至於cookie都有可能發生。
2.密碼欄位使用加密或雜湊值(Hash)保護
針對密碼欄位,可使用DES、甚至RSA等加密演算法或是SHA1、MD5等常用的密碼雜湊函式取代密碼明碼儲存於資料庫中,如此可減少因資料庫內容外洩衍生的風險。
3.限制Web應用的資料庫的操作權限
給用戶提供僅僅能夠滿足其工作的最低權限,從而最大限度的減少注入攻擊對資料庫的危害。
4.在發布之前使用SQL注入檢測工具進行檢測
網上有很多可以檢測SQL注入的工具,例SQLMap、SQLninja等都能夠及時修補被發現的SQL注入漏洞。
結語:
SQL注入是危害相當大的安全漏洞。近年來利用SQL注入攻擊的攻擊次數和造成的破壞程度規模都大幅度增加,所以對於我們平常編寫的Web應用,應該對於每一個小細節都要非常重視,以上就是此次的介紹。
Reference:
1.
2. https://sites.google.com/site/chengshixuexipingtai/sql/ql-injection-de-jian-jie-yu-yu-fang
3. https://blog.darkthread.net/Files/DKTD-SQLInjectionCase.pdf