淺談女站長12年建站風險經驗,讓您的網站更安全
淺談女站長12年建站風險經驗,讓(rang)您的網站更安全
我(wo)想寫這個(ge)文章,告訴一些開始學習寫程(cheng)序的人,怎(zen)么讓他的代碼更安全(quan)。
從我(wo)寫ASP到(dao)現在,大約有12年了,我(wo)寫ASP的時候,那時用 WIN NT 4.0環境,安全(quan)性很不好,在地址后(hou)加幾個特(te)殊字符
,就可以(yi)看到(dao)ASP的源代碼了, 后來,在多(duo)年寫(xie)ASP的過程中(zhong),碰到(dao)無數的黑(hei)客試圖黑(hei)我作的網站,花樣(yang)百出,因此我一直特別(bie)
注重程序(xu)的安全性(xing)。
現在為(wei)(wei)止,很久沒有寫ASP了,改為(wei)(wei)用c#寫 ASP.NET,不可(ke)否認,ASP.NET由于結(jie)構的關系,確實容(rong)易比ASP做得更安全,
但是(shi),在(zai)ASP中幾(ji)乎所有潛(qian)在(zai)的安全危險,在(zai)ASP.NET中幾(ji)乎都存在(zai),好處是(shi)ASP.NET源代碼不(bu)開放,因此(ci),黑客不(bu)太容易琢磨你
這個系(xi)統的(de)代碼(ma)后(hou),作很有針對性的(de)攻(gong)擊。
實際上,我認為,不管ASP,ASP.NET,PHP,JSP,甚至(zhi)是C/S結(jie)構的(de)程(cheng)序,都可能面臨兩個主要(yao)的(de)共同的(de)安全威脅:
1. 注(zhu)入SQL。
2. 上傳(chuan)木馬。
而對網站程序,或是所有B/S結構的程序的開發者(zhe)而言,他們要(yao)作的,主(zhu)要(yao)就是防這(zhe)兩項,其(qi)它的都是小問題(ti)了,這(zhe)兩個搞定,
網站一般就不那(nei)么容易(yi)被(bei)黑了。
1. 注入(ru)SQL,我(wo)們(men)先(xian)看(kan)看(kan)什么是SQL注入(ru),就是想辦法提交一個(ge)特殊的字(zi)符串,改(gai)變(bian)你的SQL語句,讓其(qi)變(bian)成其(qi)它的意思,
達到(dao)黑客的目的,我(wo)舉個(ge)非常(chang)簡單例子(zi), 比(bi)如(ru),我(wo)要驗證一個(ge)用戶(hu)的用戶(hu)名和密碼,如(ru)果找到(dao)了這個(ge)用戶(hu),就讓他登錄,很多
入門的人,會寫這么一個SQL語句(ju):
SELECT * FROM USERS WHERE UserName='ADMIN' and PassWord ='123456'
這個(ge)語(yu)句(ju)看起來沒問(wen)題(ti),從用戶(hu)輸(shu)入的文本(ben)框中,得到用戶(hu)名和密(mi)碼,然后用他們來組(zu)裝SQL語(yu)句(ju),如果找到這個(ge)記錄,說明(ming)用戶(hu)
名和密碼正確,讓他(ta)登(deng)錄,如(ru)果(guo)找不到(dao),說明錯誤(wu),不讓他(ta)登(deng)錄,這看起(qi)來很完(wan)美,但實際上,這個(ge)語句完(wan)全(quan)(quan)沒(mei)有安全(quan)(quan)性,如(ru)果(guo)
用(yong)戶(hu)在(zai)密碼(ma)那里, 輸入一個 ' or 1=1 ,這樣(yang)一樣(yang),我們(men)看(kan)這個語句成了什(shen)么呢(ni)?
SELECT * FROM USERS WHERE UserName='ADMIN' and PassWord ='' or 1=1
好了(le), 這樣他就能以ADMINA的(de)身份登錄了(le),我們再想一下,如果這個(ge)黑客,他多花點心思,就可以寫(xie)入一些修改數(shu)據庫,羅
列數(shu)據(ju),破(po)壞數(shu)據(ju)的(de)語句,這就是(shi)SQL注入。
那(nei)怎么注入SQL語句呢?
方(fang)法很(hen)多,最簡單的, 比如我們看很(hen)多網站,都有這(zhe)樣的地(di)址,比如: 這(zhe)
樣的地(di)址。這(zhe)里我(wo)們(men)要(yao)用 menuid 這(zhe)個參數,往SQL語句(ju)中傳(chuan)值,于是這(zhe)成了一個注入(ru)(ru)的入(ru)(ru)口,這(zhe)是最簡單的。
還有一種(zhong),很(hen)多網頁上,都(dou)要填寫表單,比如作站內搜索,我們知道這(zhe)個文本框提交之后,也會用(yong)來(lai)組(zu)裝(zhuang)SQL語句,這(zhe)也
成了注入的切(qie)入點。
第三種(zhong),用COOKIES,很(hen)多用站點,他會用一些(xie)COOKIES來保存一些(xie)用戶數(shu)據,比(bi)如讓用戶不掉線,過了SESSION的有效期
后,用(yong)COOKIES中(zhong)的(de)數據(ju)登錄一(yi)次,用(yong)戶看起來就不會掉線了(le)。但這個COOKIES是可能(neng)被(bei)有的(de)軟件改寫的(de),于(yu)是成了(le)SQL注入的(de)來
源。
如(ru)何防(fang)止SQL注入?
從(cong)上面,我(wo)們(men)看到,凡是SQL注(zhu)入,黑(hei)客必然會(hui)想辦法提(ti)交一些特殊的字符串給我(wo)們(men)的程序,組(zu)裝出一個(ge)異常的SQL字符串,
那(nei)么,實(shi)際(ji)上要仿SQL注入,本質上,就是要對客(ke)戶端提交的數(shu)據小(xiao)心在意,我們可以用下面(mian)的辦法讓黑客(ke)的招(zhao)數(shu)失效(xiao)。
第一, 過濾,所(suo)以要用來(lai)組(zu)裝SQL語句(ju),并且(qie)這數據(ju)的來(lai)源(yuan)是是從(cong)客戶端的來(lai)字符串(chuan),我們都對它進行過濾,把一些(xie)危
險可能用(yong)來(lai)注入SQL但(dan)實(shi)際上并不常用(yong)字(zi)符串過濾(lv)掉,比如單引號(hao),大(da)于號(hao),小于號(hao),等于號(hao),空格之類(lei),把這些(xie)過濾(lv)之后,黑
客就沒法(fa)組(zu)裝(zhuang)出(chu)(chu)正確(que)的(de)SQL語句,程序執行(xing)到那里就會出(chu)(chu)錯。 它就不能(neng)得逞了。
第二(er),嚴謹(jin)規范的語(yu)句,這(zhe)主(zhu)要是寫 Request 時要小心。很(hen)多人(ren),不管讀COOKIES, GET提(ti)交(jiao)的數據,POST 提(ti)交(jiao)的數
據, 統(tong)統(tong)用一(yi)個 Request 來(lai)解決, 這個是(shi)很危險的(de)。這是(shi)怎么回事呢?有一(yi)次(ci),我(wo)發現我(wo)寫的(de)程序,被人注入了,因為(wei)每
個語(yu)句(ju)去寫過濾的代碼太(tai)累了,所以我就在程序的前面(mian),寫了一個遍歷所有GET,POST提交的數據的程序,只要發現(xian)這里面(mian)有非法(fa)
字符,就過(guo)濾掉,按理說應(ying)該很安(an)全呀,結果后來,我發(fa)現我的程序,所有獲取數據時,都是寫的Request[“A”],這樣(yang)的代碼(ma)
,沒(mei)有區(qu)別,結果黑客(ke)就自己假造了一個(ge)COOKIES,利(li)用(yong)COOKIES比(bi)較優先,從(cong)而繞過了我(wo)的過濾,成功的注入SQL, 從(cong)此之后,
我就(jiu)認真(zhen)的(de)成: Request.Form;Request.QueryString;Request.Cookies;
第(di)三(san),用(yong)存(cun)儲過程,有時,我們會(hui)碰(peng)到一些不(bu)能過濾,但(dan)又要用(yong)來作查詢條件(jian)的東西(xi),這時怎(zen)么辦(ban)呢?用(yong)存(cun)儲過程,把這
些本來(lai)要用來(lai)組裝(zhuang)SQL語句的字符串,變成存儲過程(cheng)的參(can)數,在(zai)存儲過程(cheng)中查詢(xun),這樣(yang),就避(bi)免了(le)組裝(zhuang)SQL語句,不給黑客機會。
但也要(yao)注意,有一(yi)(yi)次,我看(kan)(kan)到一(yi)(yi)個程序員作的程序,他(ta)(ta)說他(ta)(ta)用了存儲(chu)過程,還是(shi)被黑(hei)了,怎么回事呢?我看(kan)(kan)看(kan)(kan), 發現這(zhe)人(ren),好
家伙(huo),他把參(can)數(shu)傳進去,在(zai)存儲過程中(zhong)過程中(zhong)組裝成一個 SQL字(zi)符串,再 EXEC 執行他, 暈呀。
我前面寫過一些我的經驗,有朋(peng)友(you)說(shuo)要源代碼,其實,我覺得了(le)解(jie)方法是最重要的,道(dao)理懂了(le),那(nei)幾個代碼,還不是很容
易(yi)的事?你不懂道理(li),拿到代(dai)碼(ma)又有(you)何用(yong)?所以,我(wo)注(zhu)重于介(jie)紹初學者(zhe)一(yi)(yi)些方法,一(yi)(yi)些思路,而不是給一(yi)(yi)堆(dui)代(dai)碼(ma)了事。
今(jin)天 先(xian)寫(xie)(xie)這(zhe)些,其它的安全方面的問題,我有(you)時(shi)間接著寫(xie)(xie),如果(guo)有(you)興趣的朋友, 可以(yi)到
耐思尼克和我交流,我是耐思尼克虛擬主機SQL數據庫這個CMS系統的作者,還需要大家多支持。//szjicheng.cn/vhost/ahosting.php?s=lily
