vim 從嫌棄到依賴(6)——插入模式
作為一個真正的程式設計師,必須有高度的“安全意識”,因為我們作出的軟體執行在複雜的環境中,不能把不該有異常拋給使用者,更不能把漏洞留給“黑客”,當然也不能把“操作失誤”作為系統出錯的理由。
那麼我們應該如何才能寫出一個“安全”的軟體呢?其實問題就在我們的程式旮旯中,看你是否用心去看哪些所有可能引起問題的程式碼。下面列舉一例說明,我們的資料同步程式需要在目標資料庫執行一點點(就一點點,你看下面的程式碼就知道)SQL語句,按照原來的設計,這是不允許的,因為可能引起安全問題,但是現在既然“開了一扇窗”,就要“增加十層網”,我們來看看應該怎麼樣架起這個防火牆:
PWMIS.DataProvider.Data .AdoHelper db= this.GetDbHelper(); if (tableName == "TB_SYS_SQL") { foreach (EntityBase entity in entitys) { object obj = entity.PropertyList("sqlstr"); if (obj != null) //@1 { string sqlstr = obj as string ;//@2 if (!string.IsNullOrEmpty(sqlstr)) //@3 { //目前只執行該條型別的SQL語句 if (sqlstr.ToLower().StartsWith ("delete from jjzb")) //@4 { int count = db.ExecuteNonQuery(sqlstr.Split (';')[0]); //@5,過濾;號後的其它語句,避免SQL注入 this.Talk(string.Format("執行SQL語句{0} ,{1}行記錄受影響。 ", sqlstr, count)); } } } } }
--------------------
我們來仔細分析上面的程式碼是怎麼遵循“安全意識”的,
@1,先判斷 obj 是否為空,如果不判斷,下面的程式碼就可能出錯;
@2,將 變數 obj 轉換成一個字串物件,如果使用下面的方式轉換,有可能出現錯誤:
string sqlstr=(string)obj;
當然還有其它安全的轉換方式,大家可以去找找看;
@3,轉換可能不成功,需要再此判斷字串物件是否為空引用或者空字串,否則下面的查詢會出錯;
@4,sqlstr.ToLower(),確保它可以和後面的字串比較,避免大小寫問題;
@5,sqlstr.Split(';') 這句將輸入的SQL字串進行拆分,為什麼要這樣做?我們看看加入它的值是下面的 SQL語句會在呢麼樣:
delete from jjzb where jjdm='KF001' ;drop table tb_user--
如果有人哪天輸入了這樣的一條語句,那DBA或者系統管理員就該哭死了,sqlstr.Split(';')[0] 確保程式只會執行分號前面的SQL語句(該語句在步驟4已經確保安全了),從而不會有SQL注入的問題。
也許有人說了,這些SQL語句是我用後臺管理工具輸入的,很安全,可以確保沒有問題,不用這麼麻煩來判斷吧?也許你只輸入了一個空格,也許你的資料在傳輸過程中被黑客截獲... ...
也許,你也會說,加一個 try{...}catch{...} 不就好了嗎?這只是掩蓋了問題當並沒有解決問題。
“不要相信別人給你的任何輸入”,誰知道這是仙女還是魔鬼呢?
安全問題無處不在,仔細檢查一下你的程式旮旯,不要放過它,否則,你就可能後悔,“成功近在咫尺”卻又“檫肩而過”。