動態生成Sql命令時沒有對用戶輸入的數據進行驗證是Sql注入攻擊得逞的主要緣由
好比一個在線書店,能夠根據用戶的輸入關鍵字搜索相關的圖書。html
string name = GetUserInput("BookName"); string script = "select table_book where book_name like '%" + name + RunSql(script) RunSql(script);
若是sql
name= "'; select @@servername where ''='";
這樣就能夠獲得DB Server的名字.
還以在線書店爲例,用戶只有登錄後才能察看本身的賬戶信息,這樣作是不容置疑的,然而用戶驗證的代碼以下shell
//id和password直接來自用戶的輸入。未作處理
數據庫
string id = GetUserInput("UserID"); string password = GetUserInput("UserPassword"); tring script = "select * from table_user where User_ID = '" + id + "' and User_Password? = '" + password + "' "; RunSql(script);
若是用戶輸入的password爲「' or ''=' 」,那麼生成的script就爲:安全
select * from table_user where User_ID = 'UserID' and User_Password = '' or ''=''
這樣一來,即便不知道用戶的密碼也能夠察看該用戶的賬戶信息了服務器
再好比,入侵者會把一些巧妙假裝的代碼嵌入到你動態生成的Sql命令中,好比:
數據庫設計
Delete table_Book where 1 = 1 use master--
上面的例子都是一些簡單的示例,攻擊者還可能經過sql的漏洞對操做系統進行攻擊,好比運行
[xp_cmdshell],[xp_regread]spa
固然實際上的攻擊沒有這麼簡單,攻擊者還會利用系統設計的其餘漏洞。好比程序把數據庫返回的出錯信息沒有進行轉換就直接輸出給用戶看,那麼攻擊者就設計一些sql語句誘導系統返回須要的信息操作系統
從上面的這些例子能夠看出,對數據庫訪問權限的設計不當,給與每個數據庫鏈接太多的權限,甚至dbo或sa的權限,也是sql注入式攻擊利用的主要漏洞之一。設計
防範sql注入式攻擊
最小權限原則。特別是不要用dbo或者sa帳戶,爲不一樣的類型的動做或者組建使用不一樣的帳戶,最小權限原則適用於全部與安全有關的場合
對用戶輸入進行檢查。對一些特殊字符,好比單引號,雙引號,分號,逗號,冒號,鏈接號等進行轉換或者過濾;使用強數據類型,好比你須要用戶輸入一個整數,就要把用戶輸入的數據轉換成整數形式;限制用戶輸入的長度等等。這些檢查要放在server運行,client提交的任何東西都是不可信的
使用存儲過程。若是必定要使用sq語句,那麼用標準的方式組建sql語句,好比能夠利用parameters對象,避免用字符串直接拼sq命令。
當sql運行出錯時,不要把數據庫返回的錯誤信息所有顯示給用戶,錯誤信息常常會透露一些數據庫設計的細節
針對經常使用的sql注入式攻擊方式對症下藥