close

開宗名訓,老祖宗名言:「 害人之心不可有,防人之心不可無。 」

以下若要測試,請自己建立資料測試。

 

最近常常在寫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

字長了點,但效果一樣,寫法也差不多。

 

初學者不一定一次就可以寫到位,但程式功力會在時間長河中慢慢的增長。

第一次練習時寫不好,就寫第二次、第三次來試。

反正不要在正式時寫錯就沒事了。

若真的發現到錯,那就趕快花時間改掉錯誤吧。

但若報給資訊的上司後,上司依舊不在意這個問題,那就看自己有沒有空啦

畢竟不是每個資訊主管都會理這個,可能還會說:「 這個不會怎樣的,等出事了再來改。」

但真正出事後,主管會不會扛這個責任,就看運氣了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Jiang Ying-Fu 的頭像
    Jiang Ying-Fu

    Jiang Ying-Fu的部落格

    Jiang Ying-Fu 發表在 痞客邦 留言(0) 人氣()