開宗名訓,老祖宗名言:「 害人之心不可有,防人之心不可無。 」
以下若要測試,請自己建立資料測試。
最近常常在寫Web動態網頁
也看了很多前浪、後浪寫的程式
都發現到有一些跟資料庫查詢有關的缺失。
大多的缺失不外乎是使用「*」查詢,或是Where條件有資料隱碼的bug
要不就是同一個頁面,針對同一個資料表,使用同一個語法重覆執行了n次。
資料隱碼的問題,說大不大,說小不小,但這依舊是一些人喜歡鑽的漏洞。
string id = Request("id").toString();
string SQL = "Select * from Student Where id='" + id + "'";
這個語法應該令很多人懷念,學生時代常見的語法之一啊~~~~~~~
當我們把上面的SQL程式,併到Web頁面,就可以用一段網址來直接查詢了
例如:http://網址/Studtent.aspx?id=887081
這時把資料轉換一下,就會如下所示:
string id ="887081";
string SQL = "Select * from Student Where id='887081'";
這個語法看起來沒什麼問題,我們可以直接查詢到學號887081的資料
但若我們在Request("id")這個值上面動個手腳,就會出現問題了
例如:
http://網址/Studtent.aspx?id=887081'or%201=1%201='
或是在文字盒<Input Type="Text" id ="id">裡面填入「887081'or 1=1 or 1='」
這時我們的SQL語法就會變成了
string SQL = "Select * from Student Where id='887081'or 1=1 or 1=''";
不信邪的人可以自己建測試資料去試,絕對不要拿正式資料和別人的資料、網站來測試
絕對會看到一個有如芝麻開門後的效果,所有在Student內的資料全列出了來。
任你防火牆多麼的高級,網管工程師多麼的勤勞
所有的辛苦都在這一瞬間破功了,去了了囉~~~~~
第一個語法是給人看光光,第二個是站著不動給人一路砍到底
當然若這個洞是故意留下的,那就是另一回事了。
這時我們要提防三個常見的小東西
1.特殊符號:「'」單引號,「"」雙引號,「 」空白(在網址列空白是用%20呈現)
2.關鍵字:「Select」「Delete」「Insert」「Update」「or」
3.判斷式:「1=1」這類永都為true的條件
在初學的階段
我們最常見的做法
是在接收到值時,順手把值給檢查檢查
例如:
在單引號上面,我們可以這樣做
string id = Request("id").toString();
id = id.Replace("'","''"); 把1個單引號改成2個單引號
未置換前(1):string SQL = "Select * from Student Where id='887081'or 1=1";
置換掉後(2):string SQL = "Select * from Student Where id='887081''or 1=1";
雖然只多一個單引號,但最後的結果會差很大
語法(1)會把所有的名單列出
語法(2)則是查詢失敗「' 之處的語法不正確。」
只要再針對失敗時的結果另外輸出,影響就縮小了。
但現在這個時代
我們可以用更安全方便的方法來處理
而「SqlParameter」則 會是我們的好幫手
以ASP.Net C#為例
DataSet ds = new DataSet();
string id = Request("id").toString();
string SQL = "Select * from Student Where id=@id";
SqlParameter sp = new SqlParameter("@id" , SqlDbType.Char , 6);
sp.Value = id;
SqlCommand cmd = new Command(conn);
cmd.CommandText = SQL;
cmd.Parameters.Add(sp);
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
da.Fill(ds,"Student");
用這種方式來取資料,雖然程式碼會比沒處理之前多了一些
但安全最重要,麻煩一點沒關係。
而且前面列的三種問題,可以說大多被SqlParameter一次自動處理掉了。
當然這個不止在ASP.Net才有
Java內也有這類的東西,叫做「PreparedStatement」
來自java.sql.Statement
字長了點,但效果一樣,寫法也差不多。
初學者不一定一次就可以寫到位,但程式功力會在時間長河中慢慢的增長。
第一次練習時寫不好,就寫第二次、第三次來試。
反正不要在正式時寫錯就沒事了。
若真的發現到錯,那就趕快花時間改掉錯誤吧。
但若報給資訊的上司後,上司依舊不在意這個問題,那就看自己有沒有空啦
畢竟不是每個資訊主管都會理這個,可能還會說:「 這個不會怎樣的,等出事了再來改。」
但真正出事後,主管會不會扛這個責任,就看運氣了。
留言列表