深入淺出SQL注入,深入淺出sql
之前在做學生資訊管理系統和機房收費系統的時候,對於SQL注入的問題已經是司空見慣,但是並沒有真正的地形象生動的理解SQL注入到底是什麼玩意兒.直到這次做牛腩才在牛老師的舉例之下,明白了原來SQL注入是真的很危險啊.
問題提出:
我們先來構造一個簡單的添加新聞類別的程式,在動態網頁上添加一個TextBox控制項,一個Button控制項,一個GridView控制項。布局如所示:
然後為控制項編寫代碼如下:
先來看SQLHelper類中用來執行sql語句的函數
<span style="font-size:18px;">public int ExecuteNonQuery(string sql) { int res; try { cmd = new SqlCommand(sql,GetConn()); res = cmd.ExecuteNonQuery(); } catch (Exception ex) { throw ex; } finally { if (conn.State ==ConnectionState.Open) { conn.Close(); } } return res; }</span>
然後是用來進行插入資料的函數Insert
<span style="font-size:18px;"> public bool Insert(string caName) { bool flag = false; string sql = "insert intocategory(name) values('"+caName +"')"; int res =sqlhelper.ExecuteNonQuery(sql); if (res > 0) { flag = true; } return flag; }</span>
最後是在頁面代碼中編寫按鈕的單擊事件代碼
<span style="font-size:18px;"> protected void Button1_Click(object sender,EventArgs e) { string caName = TextBox1.Text; bool b = newCategoryDAO().Insert(caName); Response.Write(b); GridView1.DataSource = newCategoryDAO().SelectAll(); GridView1.DataBind(); }</span>
調試沒問題之後,運行程式,結果如
當我們在輸入框中輸入“奇聞異事')delete category where id=5--”之後,單擊按鈕,結果如下:
當時我看到這個結果的時候,很是震驚,就這麼輕易的把資料庫裡的資料刪除了?這是為什麼呢?我們把代碼中的SQL語句提取出來,然後將輸入的內容也放進去,來分析一下原因,如
這隻是SQL注入的一個簡單的例子而已,還有好多種形式的SQL注入。只要能夠擷取你的資料庫表名(對於高手來說,這個so easy),而且你的代碼沒有經過安全性最佳化,那麼我就可以隨意更改甚至刪除你的資料,上面的只是刪除了一條記錄,如果把語句改成delete category,那麼整個表的資料將會被清空,後果很嚴重啊。
解決方案:
一種辦法就是將輸入的內容參數化,即將原本拼接SQL語句的方式變成向SQL語句中傳入參數。具體來講,就是將Insert函數改造一下,並且將SQLHelper類中的相應函數也改寫一下,代碼如下:
先來看SQLHelper的函數如何改寫:
<span style="font-size:18px;">public int ExecuteNonQuery(string sql ,SqlParameter [] paras) { int res; using (cmd =new SqlCommand (sql ,GetConn ())) { cmd.Parameters.AddRange(paras ); res =cmd .ExecuteNonQuery (); } return res; }</span> 然後是Insert函數的最佳化代碼:
<span style="font-size:18px;"> public bool Insert(string caName) { bool flag = false; string sql = "insert into category(name) values(@caName)"; SqlParameter[] paras = new SqlParameter[]{ new SqlParameter ("@caName",caName ) }; int res = sqlhelper.ExecuteNonQuery(sql, paras); if (res > 0) { flag = true; } return flag; }</span> 最佳化之後調試沒問題,運行程式,結果如下:
我們在輸入框中輸入“奇聞異事')delete category where id=2--”,然後單擊按鈕,會出現什麼結果呢?請看:
到現在為止,相信你對SQL注入一定有了一個直觀的認識和理解,當初做系統的時候只是知道在輸入框中輸入奇數個英文狀態下的單引號,會讓你的系統報錯甚至死掉,並不知道還可以通過拼接SQL語句對內部資料庫進行操作,從而對SQL注入的危害性沒有那麼深刻的認識,現在終於明白了原來問題很嚴重啊!