最近發現,很久以前的一個
項目中的查詢竟然會注入sql,原來是使用的通用的存儲過程分頁,里面有個參數是@wherestr,這個參數是在拼接sql,所以會造成注入,這個真是蛋疼的問題。
很多人沒發現這個問題,所以在這里說一說,也希望找到完美的解決方法,首先過濾是不行的,過濾說白了是在改變用戶的意志。所以我就寫了一個通用分頁的方法,動態拼接sql,這樣參數化就可以完全分開了
首先先說一下究竟是怎么回事
以下是先用 存儲過程分頁
分頁存儲過程是從網上隨便找的其中有個參數是@wherestr
(1)按鈕事件
public void tranDatabind(int pageindex) { StringBuilder sb = new System.Text.StringBuilder(" 1=1"); int count = 0; testClass tc = new testClass(); if (this.textBox1.Text != "") { sb.Append(" and teststr like '%"+this.textBox1.Text+"%'"); } this.dataGridView1.DataSource = tc.pagedataExecute(pageindex, sb.ToString(), out count); this.pageControler1.PageIndex = 1; this.pageControler1.RecordCount = count; }
(2)調用的tc.pagdateExecute()
public DataTable pagedataExecute(int pageindex,string wherestr,out int count) { return SqlHelper.ExecuteDataPage("Table_1", pageindex, 10, "id", "*",wherestr, "id desc", out count); }
(3)
SqlHelper.ExecuteDataPage里的wherestr參數 new SqlParameter("@Filter",where);........
我寫這些是說明我這里的確用了參數化,但是是在參數化里實行了sql拼接,這是錯誤的關鍵所在。然后查詢一個單引號


最后沒辦法,只能放棄存儲過程的分頁,寫個通用的分頁方法,雖然會損失效率但是相比sql注入和過濾是值得的。
public static DataTable ExecutePage(string tableName,string pk,string sort,int pageNumber,int pageSize,string Fields,string Filter,out int recordCount,SqlParameter[] pars) { StringBuilder sqlsb = new StringBuilder(); StringBuilder wheresb = new StringBuilder(); if (!string.IsNullOrEmpty(Filter)) { wheresb.Append("where "+ Filter); } sqlsb.Append("select count("+pk+") as recordcount from "+tableName+" "+ wheresb+";" ); if(string.IsNullOrEmpty(sort)) { sort = pk + " desc"; } if (pageNumber < 1) { pageNumber = 1; } string startid = ((pageNumber - 1) * pageSize + 1).ToString(); string endid = (pageNumber * pageSize).ToString(); sqlsb.Append("select * from (select " + Fields + ",row_number() over( order by " + sort + ") as rownum from " + tableName + " " + wheresb + ") as T where rownum between "+startid+" and "+endid); DataSet ds = new DataSet(); if (pars != null) { ds= SqlHelper.ExecuteDataset(CommandType.Text, sqlsb.ToString(), pars); } else { ds= SqlHelper.ExecuteDataset( sqlsb.ToString()); } recordCount =(int)ds.Tables[0].Rows[0]["recordcount"]; ds.Tables[1].Columns.Remove("rownum"); return ds.Tables[1]; }
最后希望大家能說說自己的看法,不過千萬別說什么過濾之類的------
-------------------------------------歡迎指導討論-------------------------------