深入淺出SQL注入

 之前在做學生信息管理系統和機房收費系統的時候,對於SQL注入的問題已經是司空見慣,但是並沒有真正的地形象生動的理解SQL注入到底是什麼玩意兒.直到這次做牛腩纔在牛老師的舉例之下,明白了原來SQL注入是真的很危險啊.

問題提出:

    我們先來構造一個簡單的添加新聞類別的程序,在動態網頁上添加一個TextBox控件,一個Button控件,一個GridView控件。佈局如下圖所示:


然後爲控件編寫代碼如下:

先來看SQLHelper類中用來執行sql語句的函數

[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <span style="font-size:18px;">public int ExecuteNonQuery(string sql)  
  2.        {  
  3.            int res;  
  4.            try  
  5.            {  
  6.                cmd = new SqlCommand(sql,GetConn());  
  7.                res = cmd.ExecuteNonQuery();  
  8.            }  
  9.            catch (Exception ex)  
  10.            {  
  11.                throw ex;  
  12.            }  
  13.            finally {  
  14.                if (conn.State ==ConnectionState.Open)  
  15.                {  
  16.                    conn.Close();  
  17.                }  
  18.            }  
  19.            return res;  
  20.        }</span>  

然後是用來進行插入數據的函數Insert

[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <span style="font-size:18px;"public bool Insert(string caName)  
  2.         {  
  3.             bool flag = false;  
  4.             string sql = "insert intocategory(name) values('"+caName +"')";  
  5.             int res =sqlhelper.ExecuteNonQuery(sql);  
  6.             if (res > 0)  
  7.             {  
  8.                 flag = true;  
  9.             }  
  10.             return flag;  
  11.         }</span>  

最後是在頁面代碼中編寫按鈕的單擊事件代碼

[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <span style="font-size:18px;"protected void Button1_Click(object sender,EventArgs e)  
  2.         {  
  3.             string caName = TextBox1.Text;  
  4.             bool b = newCategoryDAO().Insert(caName);  
  5.             Response.Write(b);  
  6.             GridView1.DataSource = newCategoryDAO().SelectAll();  
  7.             GridView1.DataBind();  
  8.         }</span>  

調試沒問題之後,運行程序,結果如下圖


當我們在輸入框中輸入“奇聞異事')delete category where id=5--”之後,單擊按鈕,結果如下:


當時我看到這個結果的時候,很是震驚,就這麼輕易的把數據庫裏的數據刪除了?這是爲什麼呢?我們把代碼中SQL語句提取出來,然後將輸入的內容也放進去,來分析一下原因,如下圖

這只是SQL注入的一個簡單的例子而已,還有好多種形式的SQL注入。只要能夠獲取你的數據庫表名(對於高手來說,這個so easy),而且你的代碼沒有經過安全性優化,那麼我就可以隨意更改甚至刪除你的數據,上面的只是刪除了一條記錄,如果把語句改成delete category,那麼整個表的數據將會被清空,後果很嚴重啊。

解決方案:

一種辦法就是將輸入的內容參數化,即將原本拼接SQL語句的方式變成向SQL語句中傳入參數。具體來講,就是將Insert函數改造一下,並且將SQLHelper類中的相應函數也改寫一下,代碼如下:

先來看SQLHelper的函數如何改寫:

[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <span style="font-size:18px;">public int ExecuteNonQuery(string sql ,SqlParameter [] paras)  
  2.        {  
  3.            int res;  
  4.            using (cmd =new SqlCommand (sql ,GetConn ()))  
  5.            {  
  6.                cmd.Parameters.AddRange(paras );  
  7.                res =cmd .ExecuteNonQuery ();  
  8.            }  
  9.            return res;  
  10.        }</span>  
        然後是Insert函數的優化代碼:

[csharp] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <span style="font-size:18px;"public bool Insert(string caName)  
  2.         {  
  3.             bool flag = false;  
  4.             string sql = "insert into category(name) values(@caName)";  
  5.             SqlParameter[] paras = new SqlParameter[]{  
  6.                 new SqlParameter ("@caName",caName )  
  7.             };  
  8.             int res = sqlhelper.ExecuteNonQuery(sql, paras);  
  9.             if (res > 0)  
  10.             {  
  11.                 flag = true;  
  12.             }  
  13.             return flag;  
  14.         }</span>  
        優化之後調試沒問題,運行程序,結果如下:

    我們在輸入框中輸入“奇聞異事')delete category where id=2--”,然後單擊按鈕,會出現什麼結果呢?請看下圖:

到現在爲止,相信你對SQL注入一定有了一個直觀的認識和理解,當初做系統的時候只是知道在輸入框中輸入奇數個英文狀態下的單引號,會讓你的系統報錯甚至死掉,並不知道還可以通過拼接SQL語句對內部數據庫進行操作,從而對SQL注入的危害性沒有那麼深刻的認識,現在終於明白了原來問題很嚴重啊!

            

       


發佈了39 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章