存儲過程分頁的注入問題以及解決


最近發現,很久以前的一個

項目中的查詢竟然會注入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];

        }

 最后希望大家能說說自己的看法,不過千萬別說什么過濾之類的------

 -------------------------------------歡迎指導討論-------------------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM