sql注入是被談的很多的一個(gè)話題,有很多的方法能夠?qū)崿F(xiàn)sql的防注入,在這里就簡(jiǎn)單說(shuō)一下如果使用HttpModule來(lái)實(shí)現(xiàn)sql的防注入。
在項(xiàng)目中添加一個(gè)類(lèi)讓其實(shí)現(xiàn)IHttpModule接口。IHttpModule接口有兩個(gè)方法 Init 和 Dispose。然后在Init方法中來(lái)訂閱
AcquireRequestState事件。
Code ;zPh0Ml&rb$KH"H(M0 public void Dispose()ITPUB個(gè)人空間4t[5~C)Wza3^0~ { 2mz$k9x#E*R0 ITPUB個(gè)人空間 y*vGOz+} }
public void Init(HttpApplication context) h|+c]u/WF2I(m0 {ITPUB個(gè)人空間.`z#w {&E"V context.AcquireRequestState += new EventHandler(context_AcquireRequestState); p$q)m zX)DG^2g#y0 } 7@,R1[sN/H? ~0
為什么是AcquireRequestState 事件而不是Begin_Request呢 ,因?yàn)樵贐egin_Request執(zhí)行的時(shí)候還沒(méi)有加載session狀態(tài),而在處理的時(shí)侯
可能會(huì)用到session。
在AcquireRequestState 事件中我們就要進(jìn)行相應(yīng)的處理了,思路如下,一般網(wǎng)站提交數(shù)據(jù)只有兩個(gè)地方,表單和url,所以就在該事件中將從這兩處提交的數(shù)據(jù)截取,判斷是否有一些危險(xiǎn)字符,然后做相應(yīng)處理。代碼如下
Code { a/Go~&O0private void context_AcquireRequestState(object sender, EventArgs e)ITPUB個(gè)人空間;q!Y#of] i0E {ITPUB個(gè)人空間i2]'\8C s t HttpContext context = ((HttpApplication)sender).Context;
tryITPUB個(gè)人空間6JC g9Y4e6e TQ { aF:O3rK)F_0 string getkeys = string.Empty;ITPUB個(gè)人空間/aO%y4xwK#_ string sqlErrorPage = "~/Error.aspx";//轉(zhuǎn)向的錯(cuò)誤提示頁(yè)面 Sx\(@:A0 string keyvalue = string.Empty;
string requestUrl = context.Request.Path.ToString(); W/o/l9c$e/X0 //url提交數(shù)據(jù)ITPUB個(gè)人空間 g:X$L)w iM:T%y if (context.Request.QueryString != null) &n4eohe-p(i0 {ITPUB個(gè)人空間+UAb/V M v for (int i = 0; i < context.Request.QueryString.Count; i++)ITPUB個(gè)人空間0|U'J\.yCy { O D7RA.TZJ0 getkeys = context.Request.QueryString.Keys[i];ITPUB個(gè)人空間7SBs[L keyvalue = context.Server.UrlDecode(context.Request.QueryString[getkeys]);
if (!ProcessSqlStr(keyvalue))ITPUB個(gè)人空間F:L"Sv7\a { G(D6w'}V%b0 context.Response.Redirect(sqlErrorPage); -Uh1c(Obp gC?e0 context.Response.End(); 'g Rx2aa0 break;ITPUB個(gè)人空間)R&^,er|!\U cLi }ITPUB個(gè)人空間 l;n7B,B?p*o:L P ^"K } J T3T_VX N R0 } },gL$t3zu0 //表單提交數(shù)據(jù) /?]r)j0P+O0 if (context.Request.Form. != null)ITPUB個(gè)人空間`%C[qyN { ~2[,jt5r];?(v0 for (int i = 0; i < context.Request.Form.Count; i++)ITPUB個(gè)人空間LHzK U5~ {ITPUB個(gè)人空間t \+XwpP(l6F getkeys = context.Request.Form.Keys[i]; ped8P#V#?_(rN0 keyvalue = context.Server.HtmlDecode(context.Request.Form[i]); \8RG.A1C0AX0 if (getkeys == "__VIEWSTATE") continue; If!B%H/QE0 if (!ProcessSqlStr(keyvalue))ITPUB個(gè)人空間9dZez,}7t { MB7wV ~;YE0 context.Response.Redirect(sqlErrorPage);ITPUB個(gè)人空間0oW?m'oI L context.Response.End(); 2P:g:H5qK_ KF0 break;ITPUB個(gè)人空間?u"S;ExrJ5kUcX/V } KwGHqeD;o S0 } 1Y#a+r)g fk0 }ITPUB個(gè)人空間@V zzTk4g } 9l0[ K0S5F0 catch (Exception ex)ITPUB個(gè)人空間w }4Y NP%k@6p Ch { H"O?R aL"P0^0 }ITPUB個(gè)人空間]_R W/KN } -|8i p6EC0
上面的代碼只是做了簡(jiǎn)單的處理,當(dāng)然也可以在事件中將輸入非法關(guān)鍵字的用戶(hù)ip ,操作頁(yè)面的url,時(shí)間等信息記錄在數(shù)據(jù)庫(kù)中或是記錄在日志中。而且還用到了一個(gè)叫ProcessSqlStr的方法,這個(gè)方法就是用來(lái)處理字符串的,判斷是否合法,如下
CodeITPUB個(gè)人空間/j1{{ vwCo private bool ProcessSqlStr(string str)ITPUB個(gè)人空間f_,e z,]:qx { eY)V/gE-s+K!n?G0 bool returnValue = true; C+nlGn0 tryITPUB個(gè)人空間J"BN H8[ pj { b"oo5X$p?^L/i&TZ0 if (str.Trim() != "") %Jx)@^+j w)FI A0 {ITPUB個(gè)人空間y$^~3Rt //一般將關(guān)鍵詞組配置在webconfig中 CRu y}j;LO0 //string sqlStr = ConfigurationManager.AppSettings["FilterSql"].Trim(); G e {@8k F` kF4n0 string sqlStr = "declare |exec|varchar |cursor |begin |open |drop |creat |select |truncate";
string[] sqlStrs = sqlStr.Split('|'); ;P H _7p(t5g { x6B0 foreach (string ss in sqlStrs) (Fk,q\{'f:~4t0 {ITPUB個(gè)人空間7\/h'I}u2_db if (str.ToLower().IndexOf(ss) >= 0)ITPUB個(gè)人空間k;\h6G2u~ {ITPUB個(gè)人空間HG(F]6G m_sqlstr = ss; j,||I9vr []*Q0 returnValue = false; 5`@X2Z6SV2e.P;YP0 break; P([u(q)gj"M l0 } I3va7B7g6u0 }ITPUB個(gè)人空間DrQ!UH4Pf$V)vn }ITPUB個(gè)人空間}-kC*j&H1e\j3Z}N } "QcH$O{'R^0 catchITPUB個(gè)人空間&b4i%\"K ~3Fm {ITPUB個(gè)人空間]Xk)qz4I8n-\,y returnValue = false;ITPUB個(gè)人空間-x3n%b|Ao vo }ITPUB個(gè)人空間m"h nz#N6qzX return returnValue;ITPUB個(gè)人空間&l9I,na-t Vh-o } RCS,N5|a_0
到這兒類(lèi)就寫(xiě)好了,再在web.config中做相應(yīng)的配置就大功告成
CodeITPUB個(gè)人空間'G(? q s"}x\"p^ <httpModules>ITPUB個(gè)人空間A @+{ IQ.Q&_a'E <add type="SqlHttpModule " name="SqlHttpModule"/>ITPUB個(gè)人空間!q-B([ ?)XoF </httpModules> c0R;Uhr V6I0
用這種方法很方便,只需在這一處做處理,全站都能應(yīng)用到,不過(guò)如果一個(gè)用戶(hù)想用varchar 等sql的關(guān)鍵字來(lái)做用戶(hù)名注冊(cè)的話也會(huì)被擋掉,
不過(guò)應(yīng)該沒(méi)有人這么無(wú)聊吧,呵呵!
asp.net 防SQL注入
|