




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
安全規(guī)范密級(jí):保密WEB開發(fā)安全漏洞修復(fù)方案(V1.0)文檔編號(hào):文檔名稱:WEB開發(fā)安全漏洞修復(fù)方案編寫:審核:批準(zhǔn):批準(zhǔn)日期:技術(shù)研究部
文檔修訂記錄編號(hào)版本號(hào)修訂內(nèi)容簡(jiǎn)述修訂日期作者審核1V1.0初稿2012-7678910111213141516
TOC\o"1-6"\h\z\u(V1.0) 11.1 背景 11.2 FSDP安全漏洞清單 11.3 安全漏洞修復(fù)方案 11.3.1 會(huì)話標(biāo)識(shí)未更新 11.3.2 登錄錯(cuò)誤消息憑證枚舉 21.3.3 不充分帳戶封鎖 21.3.4 跨站點(diǎn)腳本編制 31.3.5 已解密的登錄請(qǐng)求 61.3.6 跨站點(diǎn)腳本編制 91.3.7 通過框架釣魚 131.3.8 鏈接注入(便于跨站請(qǐng)求偽造) 181.3.9 應(yīng)用程序錯(cuò)誤 251.3.10 SQL注入 291.3.11 發(fā)現(xiàn)數(shù)據(jù)庫(kù)錯(cuò)誤模式 381.3.12 啟用了不安全的HTTP方法 481.3.13 發(fā)現(xiàn)電子郵件地址模式 501.3.14 HTML注釋敏感信息泄露 511.3.15 發(fā)現(xiàn)內(nèi)部IP泄露模式 521.3.16 主機(jī)允許從任何域進(jìn)行flash訪問 531.3.17 主機(jī)應(yīng)用軟件漏洞修復(fù) 531.3.18 目錄列表 541.3.19 跨站點(diǎn)請(qǐng)求偽造 551.1 需要注意的問題 56背景隨著移動(dòng)公司對(duì)信息安全的進(jìn)一步加強(qiáng),要求我們部署的系統(tǒng)必須滿足安全掃描要求。本文檔描述了安徽移動(dòng)對(duì)FSDP安全掃描的漏洞的解決方案,并作為WEB開發(fā)的安全編程規(guī)范。FSDP安全漏洞清單見《WEB開發(fā)安全漏洞清單.xlsx》安全漏洞修復(fù)方案會(huì)話標(biāo)識(shí)未更新URL00/loginAction.do安全問題描述根據(jù)WASC:“會(huì)話固定”是一種攻擊技術(shù),會(huì)強(qiáng)制用戶的會(huì)話標(biāo)識(shí)變成顯式值。固定會(huì)話標(biāo)識(shí)值的技術(shù)有許多種,會(huì)隨著目標(biāo)Web站點(diǎn)的功能而不同。從利用“跨站點(diǎn)腳本編制”到向Web站點(diǎn)密集發(fā)出先前生成的HTTP請(qǐng)求,都在這些技術(shù)范圍內(nèi)。用戶的會(huì)話標(biāo)識(shí)固定之后,攻擊者會(huì)等待用戶登錄,然后利用預(yù)定義的會(huì)話標(biāo)識(shí)值來假定用戶的聯(lián)機(jī)身份。攻擊方法登錄過程前后會(huì)話標(biāo)識(shí)的比較,顯示它們并未更新,這表示有可能偽裝用戶。初步得知會(huì)話標(biāo)識(shí)值后,遠(yuǎn)程攻擊者有可能得以充當(dāng)已登錄的合法用戶。 任何時(shí)候,只要一名用戶與應(yīng)用程序的交互狀態(tài)由匿名轉(zhuǎn)變?yōu)榇_認(rèn),應(yīng)用程序就應(yīng)該發(fā)布一個(gè)新的會(huì)話令牌。這不僅適用于用戶成功登錄的情況,而且適用于匿名用戶首次提交個(gè)人或其他敏感信息時(shí)。安全規(guī)范要求COOKIE中的登陸前JSESSIONID與登陸后JESSIONID不能相同。(只有J2EE應(yīng)用服務(wù)器為JESSIONID,其他應(yīng)用服務(wù)器可能不同)解決方案將如下代碼加入到登陸頁(yè)面(login.jsp)的最后行:<%
request.getSession().invalidate();//清空session
Cookiecookie=request.getCookies()[0];//獲取cookie
cookie.setMaxAge(0);//讓cookie過期
%>登錄錯(cuò)誤消息憑證枚舉URL00/loginAction.do安全問題描述當(dāng)試圖利用不正確的憑證來登錄時(shí),當(dāng)用戶輸入無效的用戶名和無效的密碼時(shí),應(yīng)用程序會(huì)分別生成不同的錯(cuò)誤消息。通過利用該行為,攻擊者可以通過反復(fù)試驗(yàn)(蠻力攻擊技術(shù))來發(fā)現(xiàn)應(yīng)用程序的有效用戶名,再繼續(xù)嘗試發(fā)現(xiàn)相關(guān)聯(lián)的密碼。這樣會(huì)得到有效用戶名和密碼的枚舉,攻擊者可以用來訪問帳戶。攻擊方法修改00/loginAction.do的HTTP報(bào)文頭:將參數(shù)“optrid”的值設(shè)置為“test123WithSomeChars”,除去cookie“JSESSIONID”,除去HTTP頭“Cookie=JSESSIONID”。安全規(guī)范要求對(duì)每個(gè)錯(cuò)誤的登錄嘗試發(fā)出相同的錯(cuò)誤消息,不管是哪個(gè)字段發(fā)生錯(cuò)誤,特別是用戶名或密碼字段錯(cuò)誤。解決方案LoginImpl.java類中g(shù)etLoginInfo方法,涉及到登錄錯(cuò)誤提示的都改成:“您輸入的用戶名或密碼不正確!”。
登錄超過3次數(shù)的改成:“您嘗試登陸失敗超過"+Constans.LOGIN_ERROR_TIMES+"次,請(qǐng)30分鐘后再登陸!”。
不充分帳戶封鎖URL00/loginAction.do安全問題描述發(fā)送了兩次合法的登錄嘗試,并且在其間發(fā)送了幾次錯(cuò)誤的登錄嘗試。最后一個(gè)響應(yīng)與第一個(gè)響應(yīng)相同。這表明存在未充分實(shí)施帳戶封鎖的情況,從而使登錄頁(yè)面可能受到蠻力攻擊。(即使第一個(gè)響應(yīng)不是成功的登錄頁(yè)面,也是如此。)攻擊方法修改00/loginAction.do的HTTP報(bào)文頭:除去cookie“JSESSIONID”,除去HTTP頭“Cookie=JSESSIONID”。安全規(guī)范要求多次登錄嘗試失敗后實(shí)施帳戶封鎖解決方案LoginImp.java中的getLoginInfo方法,修訂如下代碼片段://判斷登陸失敗次數(shù) if(!checkLoginError(logininfo)){ ret.setRetCode("0003"); ret.setRetDesc("您嘗試登陸失敗超過"+Constans.LOGIN_ERROR_TIMES+"次,請(qǐng)"+Constans.LOGIN_ERROR_LOCK_SECOND+"分鐘后再登錄!"); returnret; }//增加驗(yàn)證登陸錯(cuò)誤次數(shù)代碼 addLoginErrorRec(logininfo);跨站點(diǎn)腳本編制URL00/callAction.do00/loginAction.do安全問題描述可能會(huì)竊取或操縱客戶會(huì)話和cookie,它們可能用于模仿合法用戶,從而使黑客能夠以該用戶身份查看或變更用戶記錄以及執(zhí)行事務(wù)。攻擊方法Web站點(diǎn)中所包含的腳本直接將用戶在HTML頁(yè)面中的輸入(通常是參數(shù)值)返回,而不預(yù)先加以清理。如果腳本在響應(yīng)頁(yè)面中返回由JavaScript代碼組成的輸入,瀏覽器便可以執(zhí)行此輸入。因此,有可能形成指向站點(diǎn)的若干鏈接,且其中一個(gè)參數(shù)包含惡意的JavaScript代碼。該代碼將在站點(diǎn)上下文中(由用戶瀏覽器)執(zhí)行,這使得該代碼有權(quán)訪問用戶在該站點(diǎn)中具有訪問權(quán)的cookie,以及站點(diǎn)中其他可通過用戶瀏覽器訪問的窗口。攻擊依照下列方式繼續(xù)進(jìn)行:攻擊者誘惑合法用戶單擊攻擊者生成的鏈接。用戶單擊該鏈接時(shí),便會(huì)生成對(duì)于Web站點(diǎn)的請(qǐng)求,其中的參數(shù)值含有惡意的JavaScript代碼。如果Web站點(diǎn)將這個(gè)參數(shù)值嵌入在響應(yīng)的HTML頁(yè)面中(這正是站點(diǎn)問題的本質(zhì)所在),惡意代碼便會(huì)在用戶瀏覽器中運(yùn)行。安全規(guī)范要求FSDP框架中在傳遞參數(shù)時(shí)有兩個(gè)主要參數(shù)classes與common,一個(gè)指定要調(diào)用的service,一個(gè)是調(diào)用service中的方法,如果service或方法不存在,就會(huì)跳轉(zhuǎn)到錯(cuò)誤信息顯示,并將詳細(xì)的錯(cuò)誤信息顯示出來,如:callAction.do?method=call&nextPage=/oa/task/task_querylayout.jsp&classes=taskClientImpl&common=getInfoQueryDate這個(gè)URL,如果我們將URL修改一下,變成如下:
callAction.do?method=call&nextPage=/oa/task/task_querylayout.jsp&classes=taskClientImpl<script>alert(123)</script>&common=getInfoQueryDate,通過這個(gè)URL執(zhí)行時(shí)會(huì)提示service不存在,并跳轉(zhuǎn)到錯(cuò)誤頁(yè)面,同時(shí)會(huì)彈出123信息的提示窗口,同時(shí)如果我們修改common參數(shù)也能達(dá)到這種效果
解決方案web.xml增加如下配置:
<!--可能存在的跨域代碼字符串,用逗號(hào)分開-->
<context-param>
<param-name>CROSS_DOMAIN_STR</param-name>
<param-value><,>,%3C,%3E</param-value>
</context-param>
Constans.java類增加如下變量:
/**
*跨域特殊字符判斷
*/
publicstaticList<String>CROSS_DOMAIN_STR=newArrayList<String>();
FriendOneServlet.java類增加initSafetyConf安全初始化配置方法
privatevoidinitSafetyConf(){
Constans.CROSS_DOMAIN_STR.clear();
StringcrossDomainStr=getServletContext().getInitParameter("CROSS_DOMAIN_STR");
String[]crossDomainAry=crossDomainStr.split(",");
for(Strings:crossDomainAry){
Constans.CROSS_DOMAIN_STR.add(s.trim());
}
Constans.LOGIN_ERROR_TIMES=getServletContext().getInitParameter("LOGIN_ERROR_TIMES");
Constans.LOGIN_ERROR_LOCK_SECOND=getServletContext().getInitParameter("LOGIN_ERROR_LOCK_SECOND");
(Constans.CROSS_DOMAIN_STR);
("LOGIN_ERROR_TIMES="+Constans.LOGIN_ERROR_TIMES);
("LOGIN_ERROR_LOCK_SECOND="+Constans.LOGIN_ERROR_LOCK_SECOND);
}
在init方法中直接調(diào)用
在ActionFilter.java類中增加checkCrossDomain跨域特殊字符串檢查,并在doFilter中進(jìn)行判斷驗(yàn)證,如果存在特殊字符,則直接跳轉(zhuǎn)到登陸界面
修改error.jsp,此處是用于處理返回的錯(cuò)誤信息
目前是通過<html-el:errors/>標(biāo)簽方式加載錯(cuò)誤信息,此處可根據(jù)輸入的條件來進(jìn)行錯(cuò)誤注入,執(zhí)行js代碼,修改該當(dāng)如下:
一、將此錯(cuò)誤標(biāo)簽通過textarea進(jìn)行包裝,錯(cuò)誤信息是以文本方式顯示,無法執(zhí)行,如下:
<textareastyle="height:100%;width:95%;color:red"readonly=true><html-el:errors/></textarea>
同時(shí)修改BaseWebAction.java類的processError方法,將sb.append(ste[i]).append("<br>");這段代碼改為sb.append(ste[i]).append("\n");
二、無論返回什么錯(cuò)誤信息,此處只顯示“操作故障,請(qǐng)確認(rèn)操作是否合法或聯(lián)系管理員檢查!”啟用了不安全的HTTP方法<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>HEAD</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>SEARCH</http-method>
<http-method>COPY</http-method>
<http-method>MOVE</http-method>
<http-method>PROPFIND</http-method>
<http-method>PROPPATCH</http-method>
<http-method>MKCOL</http-method>
<http-method>LOCK</http-method>
<http-method>UNLOCK</http-method>
</web-resource-collection>
<auth-constraint>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
已解密的登錄請(qǐng)求URL00/loginAction.do安全問題描述用戶登錄密碼為明文攻擊方法可通過http報(bào)文截取登錄用戶密碼安全規(guī)范要求發(fā)送敏感信息時(shí),始終使用SSL和HTTPPOST方法解決方案修改server.xml
<Connectorprotocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443"minSpareThreads="5"maxSpareThreads="75"
enableLookups="true"disableUploadTimeout="true"
acceptCount="100"
maxThreads="200"
scheme="https"secure="true"SSLEnabled="true"
clientAuth="false"sslProtocol="TLS"
keystoreFile="D:/apache-tomcat-6.0.18/server.keystore"
keystorePass="friendone"/>
標(biāo)紅的地方注意,要與附件中server.keystore存放的位置一致標(biāo)藍(lán)的8443要注意,外網(wǎng)的一律全用443端口,BOSS網(wǎng)系統(tǒng)還是全用8443端口。修改web.xml,在welcome-file-list后面增加如下配置
<login-config>
<!--AuthorizationsettingforSSL-->
<auth-method>CLIENT-CERT</auth-method>
<realm-name>ClientCertUsers-onlyArea</realm-name>
<auth-method>BASIC</auth-method>
</login-config>
<security-constraint>
<!--AuthorizationsettingforSSL-->
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>/*/oa/login.jsp為應(yīng)用登錄URL,此為公司OA則為此串*/
<url-pattern>/oa/login.jsp</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint><!--禁止不安全的http方法-->
<security-constraint>
<web-resource-collection>
<web-resource-name>fortune</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>HEAD</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint></auth-constraint>
</security-constraint>增加初始化變量: <context-param> <param-name>HTTP_URI</param-name> <param-value>8080</param-value> </context-param> 此為從https轉(zhuǎn)到http時(shí)的跳轉(zhuǎn)值,為應(yīng)用部署服務(wù)器IP地址為端口LoginAction.java修改如下:Login方法修改如下:Stringrequesturl=request.getRequestURL().toString();requesturl=requesturl.substring(requesturl.indexOf("http://")+2);requesturl=requesturl.substring(0,requesturl.indexOf(":"));response.sendRedirect("http://"+requesturl+":"+Constans.HTTP_URI+request.getContextPath()+"/loginAction.do?method=flogin&sessionid="+session.getId()); returnnull;// clearTempFile(); //returnnewActionForward("/"+Constans.PROJECT_NAME+"/frames/indexFrame.jsp");增加以下方法:publicActionForwardflogin(ActionMappingmapping,ActionFormform,HttpServletRequestrequest,HttpServletResponseresponse)throwsException{ try{ Stringvalue=request.getParameter("sessionid"); HashMapsessions=(HashMap)request.getSession().getServletContext().getAttribute("sessions"); HttpSessionsession=(HttpSession)sessions.get(value); if(session!=null){ HttpSessionnsession=request.getSession(); nsession.setAttribute(Constans.LOGIN_USER,session.getAttribute(Constans.LOGIN_USER)); sessions.put(value,nsession); session=null; } returnnewActionForward("/"+Constans.PROJECT_NAME+"/frames/indexFrame.jsp"); }catch(Exceptione){ logger.error("LoginActionExceptionError:"+e.toString()); throwe; } }修改LoginAction.java類的systemLogout方法:Stringrequesturl=request.getRequestURL().toString();requesturl=requesturl.substring(requesturl.indexOf("http://")+2); requesturl=requesturl.substring(0,requesturl.indexOf(":")); response.sendRedirect("http://"+requesturl+":"+Constans.HTTP_URI+request.getContextPath()+LOGINPAGE); returnnull;// returnnewActionForward(LOGINPAGE);跨站點(diǎn)腳本編制URL00/callAction.do00/loginAction.do安全問題描述“跨站點(diǎn)腳本編制”攻擊是一種隱私違例,可讓攻擊者獲取合法用戶的憑證,并在與特定Web站點(diǎn)交互時(shí)假冒這位用戶。這個(gè)攻擊立足于下列事實(shí):Web站點(diǎn)中所包含的腳本直接將用戶在HTML頁(yè)面中的輸入(通常是參數(shù)值)返回,而不預(yù)先加以清理。如果腳本在響應(yīng)頁(yè)面中返回由JavaScript代碼組成的輸入,瀏覽器便可以執(zhí)行此輸入。因此,有可能形成指向站點(diǎn)的若干鏈接,且其中一個(gè)參數(shù)包含惡意的JavaScript代碼。該代碼將在站點(diǎn)上下文中(由用戶瀏覽器)執(zhí)行,這使得該代碼有權(quán)訪問用戶在該站點(diǎn)中具有訪問權(quán)的cookie,以及站點(diǎn)中其他可通過用戶瀏覽器訪問的窗口。攻擊依照下列方式繼續(xù)進(jìn)行:攻擊者誘惑合法用戶單擊攻擊者生成的鏈接。用戶單擊該鏈接時(shí),便會(huì)生成對(duì)于Web站點(diǎn)的請(qǐng)求,其中的參數(shù)值含有惡意的JavaScript代碼。如果Web站點(diǎn)將這個(gè)參數(shù)值嵌入在響應(yīng)的HTML頁(yè)面中(這正是站點(diǎn)問題的本質(zhì)所在),惡意代碼便會(huì)在用戶瀏覽器中運(yùn)行。攻擊方法A.在響應(yīng)頁(yè)面中,返回發(fā)送給CGI腳本的參數(shù)值,嵌入在HTML中。例如:[請(qǐng)求]GET/cgi-bin/script.pl?name=JSmithHTTP/1.0[響應(yīng)]HTTP/1.1200OKServer:SomeServerDate:Sun,01Jan200200:31:19GMTContent-Type:text/htmlAccept-Ranges:bytesContent-Length:27<HTML>HelloJSmith</HTML>B.在HTML參數(shù)值上下文中,返回發(fā)送給CGI腳本的參數(shù)值。例如:[請(qǐng)求]GET/cgi-bin/script.pl?name=JSmithHTTP/1.0[響應(yīng)]HTTP/1.1200OKServer:SomeServerDate:Sun,01Jan200200:31:19GMTContent-Type:text/htmlAccept-Ranges:bytesContent-Length:254<HTML>Pleasefillinyourzipcode:<FORMMETHOD=GETACTION="/cgi-bin/script.pl"><INPUTTYPE=textNAME="name"value="JSmith"><br><INPUTTYPE=textNAME="zip"value="Enterzipcodehere"><br><INPUTTYPE=submitvalue="Submit"></FORM></HTML>安全規(guī)范要求通過驗(yàn)證用戶輸入未包含危險(xiǎn)字符,便可能防止惡意的用戶導(dǎo)致應(yīng)用程序執(zhí)行計(jì)劃外的任務(wù),例如:?jiǎn)?dòng)任意SQL查詢、嵌入將在客戶端執(zhí)行的Javascript代碼、運(yùn)行各種操作系統(tǒng)命令,等等。建議過濾出所有以下字符:[1]|(豎線符號(hào))[2]&(&符號(hào))[3];(分號(hào))[4]$(美元符號(hào))[5]%(百分比符號(hào))[6]@(at符號(hào))[7]'(單引號(hào))[8]"(引號(hào))[9]\'(反斜杠轉(zhuǎn)義單引號(hào))[10]\"(反斜杠轉(zhuǎn)義引號(hào))[11]<>(尖括號(hào))[12]()(括號(hào))[13]+(加號(hào))[14]CR(回車符,ASCII0x0d)[15]LF(換行,ASCII0x0a)[16],(逗號(hào))[17]\(反斜杠)解決方案LoginImpl.java類中的getLoginInfo方法,將之前的操作員工號(hào)與密碼拼接方式改成SQL變量綁定方式StringBuffersqlbuf=newStringBuffer();sqlbuf.append("SELECT.orgcode,A.userid,A.username,A.password,A.validate,A.usertype,C.orgname,C.norgcode,C.orgtype,");sqlbuf.append("now()ASlogindate,sp_genseqfunc('S','D')ASsessionid,");sqlbuf.append("(SELECTGROUP_CONCAT(B.datatype)FROMtb_userdatarelBWHEREB.userid=?)ASdatatypes,PASSWORD(?)=A.passwordASpwdiscorrect");sqlbuf.append("FROMtb_userA,tb_organizationC");sqlbuf.append("WHEREA.userid=?ANDA.effdate<=CURDATE()ANDA.expdate>=CURDATE()ANDC.orgcode=A.orgcode");web.xml增加如下配置:<!--可能存在的跨域代碼字符串,用逗號(hào)分開--><context-param><param-name>CROSS_DOMAIN_STR</param-name><param-value><,>,%3C,%3E</param-value></context-param><context-param> <param-name>GET_CROSS_DOMAIN_STR</param-name><param-value><,>,",',%,;,(,),&,+,HTTP,http,%0a</param-value></context-param>Constans.java類增加如下變量:/***跨域特殊字符判斷*/publicstaticList<String>CROSS_DOMAIN_STR=newArrayList<String>();publicstaticList<String>GET_CROSS_DOMAIN_STR=newArrayList<String>();FriendOneServlet.java類增加initSafetyConf安全初始化配置方法privatevoidinitSafetyConf(){Constans.CROSS_DOMAIN_STR.clear();StringcrossDomainStr=getServletContext().getInitParameter("CROSS_DOMAIN_STR");String[]crossDomainAry=crossDomainStr.split(",");for(Strings:crossDomainAry){Constans.CROSS_DOMAIN_STR.add(s.trim());}crossDomainStr=getServletContext().getInitParameter("GET_CROSS_DOMAIN_STR");crossDomainAry=crossDomainStr.split(",");for(Strings:crossDomainAry){Constans.GET_CROSS_DOMAIN_STR.add(s.trim());}Constans.LOGIN_ERROR_TIMES=getServletContext().getInitParameter("LOGIN_ERROR_TIMES");Constans.LOGIN_ERROR_LOCK_SECOND=getServletContext().getInitParameter("LOGIN_ERROR_LOCK_SECOND");Constans.HTTP_URI=getServletContext().getInitParameter("HTTP_URI");(Constans.CROSS_DOMAIN_STR);("LOGIN_ERROR_TIMES="+Constans.LOGIN_ERROR_TIMES);("LOGIN_ERROR_LOCK_SECOND="+Constans.LOGIN_ERROR_LOCK_SECOND);("HTTP_URI="+Constans.HTTP_URI);}在init方法中直接調(diào)用在ActionFilter.java類中增加checkCrossDomain跨域特殊字符串檢查,并在doFilter中進(jìn)行判斷驗(yàn)證,如果存在特殊字符,則直接跳轉(zhuǎn)到登陸界面修改error.jsp,此處是用于處理返回的錯(cuò)誤信息目前是通過<html-el:errors/>標(biāo)簽方式加載錯(cuò)誤信息,此處可根據(jù)輸入的條件來進(jìn)行錯(cuò)誤注入,執(zhí)行js代碼,修改該當(dāng)如下:一、將此錯(cuò)誤標(biāo)簽通過textarea進(jìn)行包裝,錯(cuò)誤信息是以文本方式顯示,無法執(zhí)行,如下:<textareastyle="height:100%;width:95%;color:red"readonly=true><html-el:errors/></textarea>同時(shí)修改BaseWebAction.java類的processError方法,將sb.append(ste[i]).append("<br>");這段代碼改為sb.append(ste[i]).append("\n");二、無論返回什么錯(cuò)誤信息,此處只顯示“操作故障,請(qǐng)確認(rèn)操作是否合法或聯(lián)系管理員檢查!”通過框架釣魚URL00/callAction.do安全問題描述網(wǎng)絡(luò)釣魚是一個(gè)通稱,代表試圖欺騙用戶交出私人信息,以便電子欺騙身份。攻擊者有可能注入frame或iframe標(biāo)記,其中含有類似受攻擊之網(wǎng)站的惡意屬性。不小心的用戶有可能瀏覽它,但并不知道他正在離開原始網(wǎng)站,沖浪到惡意的網(wǎng)站。之后,攻擊者便可以誘惑用戶重新登錄,然后獲取他的登錄憑證。攻擊方法偽造的網(wǎng)站嵌入在原始網(wǎng)站中,這個(gè)情況對(duì)攻擊者有幫助,因?yàn)樗木W(wǎng)絡(luò)釣魚企圖會(huì)披上更可信賴的外表。利用的樣本:如果參數(shù)值未經(jīng)適當(dāng)清理便反映在響應(yīng)中,那么下列請(qǐng)求:http://[SERVER]/script.aspx?parameter=<framename="evil"src="">會(huì)使響應(yīng)含有通往這個(gè)邪惡站點(diǎn)的框架。安全規(guī)范要求若干問題的補(bǔ)救方法在于對(duì)用戶輸入進(jìn)行清理。通過驗(yàn)證用戶輸入未包含危險(xiǎn)字符,便可能防止惡意的用戶導(dǎo)致應(yīng)用程序執(zhí)行計(jì)劃外的任務(wù),例如:?jiǎn)?dòng)任意SQL查詢、嵌入將在客戶端執(zhí)行的Javascript代碼、運(yùn)行各種操作系統(tǒng)命令,等等。建議過濾出所有以下字符:[1]|(豎線符號(hào))[2]&(&符號(hào))[3];(分號(hào))[4]$(美元符號(hào))[5]%(百分比符號(hào))[6]@(at符號(hào))[7]'(單引號(hào))[8]"(引號(hào))[9]\'(反斜杠轉(zhuǎn)義單引號(hào))[10]\"(反斜杠轉(zhuǎn)義引號(hào))2012-7-416:57:34154/187[11]<>(尖括號(hào))[12]()(括號(hào))[13]+(加號(hào))[14]CR(回車符,ASCII0x0d)[15]LF(換行,ASCII0x0a)[16],(逗號(hào))[17]\(反斜杠)以下部分描述各種問題、問題的修訂建議以及可能觸發(fā)這些問題的危險(xiǎn)字符:SQL注入和SQL盲注:A.確保用戶輸入的值和類型(如Integer、Date等)有效,且符合應(yīng)用程序預(yù)期。B.利用存儲(chǔ)過程,將數(shù)據(jù)訪問抽象化,讓用戶不直接訪問表或視圖。當(dāng)使用存儲(chǔ)過程時(shí),請(qǐng)利用ADO命令對(duì)象來實(shí)施它們,以強(qiáng)化變量類型。C.清理輸入以排除上下文更改符號(hào),例如:[1]'(單引號(hào))[2]"(引號(hào))[3]\'(反斜線轉(zhuǎn)義單引號(hào))[4]\"(反斜杠轉(zhuǎn)義引號(hào))[5])(結(jié)束括號(hào))[6];(分號(hào))跨站點(diǎn)腳本編制:A.清理用戶輸入,并過濾出JavaScript代碼。我們建議您過濾下列字符:[1]<>(尖括號(hào))[2]"(引號(hào))[3]'(單引號(hào))[4]%(百分比符號(hào))[5];(分號(hào))[6]()(括號(hào))[7]&(&符號(hào))[8]+(加號(hào))B.如果要修訂<%00script>變體,請(qǐng)參閱MS文章821349C.對(duì)于UTF-7攻擊:[-]可能的話,建議您施行特定字符集編碼(使用'Content-Type'頭或<meta>標(biāo)記)。HTTP響應(yīng)分割:清理用戶輸入(至少是稍后嵌入在HTTP響應(yīng)中的輸入)。請(qǐng)確保輸入未包含惡意的字符,例如:[1]CR(回車符,ASCII0x0d)[2]LF(換行,ASCII0x0a)遠(yuǎn)程命令執(zhí)行:清理輸入以排除對(duì)執(zhí)行操作系統(tǒng)命令有意義的符號(hào),例如:[1]|(豎線符號(hào))[2]&(&符號(hào))[3];(分號(hào))執(zhí)行shell命令:A.絕不將未檢查的用戶輸入傳遞給eval()、open()、sysopen()、system()之類的Perl命令。B.確保輸入未包含惡意的字符,例如:[1]$(美元符號(hào))[2]%(百分比符號(hào))[3]@(at符號(hào))XPath注入:清理輸入以排除上下文更改符號(hào),例如:[1]'(單引號(hào))[2]"(引號(hào))等LDAP注入:A.使用正面驗(yàn)證。字母數(shù)字過濾(A..Z,a..z,0..9)適合大部分LDAP查詢。B.應(yīng)該過濾出或進(jìn)行轉(zhuǎn)義的特殊LDAP字符:2012-7-416:57:34155/187[1]在字符串開頭的空格或“#”字符[2]在字符串結(jié)尾的空格字符[3],(逗號(hào))[4]+(加號(hào))[5]"(引號(hào))[6]\(反斜杠)[7]<>(尖括號(hào))[8];(分號(hào))[9]()(括號(hào))MX注入:應(yīng)該過濾出特殊MX字符:[1]CR(回車符,ASCII0x0d)[2]LF(換行,ASCII0x0a)記錄偽造:應(yīng)該過濾出特殊記錄字符:[1]CR(回車符,ASCII0x0d)[2]LF(換行,ASCII0x0a)[3]BS(退格,ASCII0x08)ORM注入:A.確保用戶輸入的值和類型(如Integer、Date等)有效,且符合應(yīng)用程序預(yù)期。B.利用存儲(chǔ)過程,將數(shù)據(jù)訪問抽象化,讓用戶不直接訪問表或視圖。C.使用參數(shù)化查詢APID.清理輸入以排除上下文更改符號(hào),例如:(*):[1]'(單引號(hào))[2]"(引號(hào))[3]\'(反斜線轉(zhuǎn)義單引號(hào))[4]\"(反斜杠轉(zhuǎn)義引號(hào))[5])(結(jié)束括號(hào))[6];(分號(hào))(*)這適用于SQL。高級(jí)查詢語(yǔ)言可能需要不同的清理機(jī)制。解決方案LoginImpl.java類中的getLoginInfo方法,將之前的操作員工號(hào)與密碼拼接方式改成SQL變量綁定方式StringBuffersqlbuf=newStringBuffer();sqlbuf.append("SELECT.orgcode,A.userid,A.username,A.password,A.validate,A.usertype,C.orgname,C.norgcode,C.orgtype,");sqlbuf.append("now()ASlogindate,sp_genseqfunc('S','D')ASsessionid,");sqlbuf.append("(SELECTGROUP_CONCAT(B.datatype)FROMtb_userdatarelBWHEREB.userid=?)ASdatatypes,PASSWORD(?)=A.passwordASpwdiscorrect");sqlbuf.append("FROMtb_userA,tb_organizationC");sqlbuf.append("WHEREA.userid=?ANDA.effdate<=CURDATE()ANDA.expdate>=CURDATE()ANDC.orgcode=A.orgcode");web.xml增加如下配置:<!--可能存在的跨域代碼字符串,用逗號(hào)分開--><context-param><param-name>CROSS_DOMAIN_STR</param-name><param-value><,>,%3C,%3E</param-value></context-param>Constans.java類增加如下變量:/***跨域特殊字符判斷*/publicstaticList<String>CROSS_DOMAIN_STR=newArrayList<String>();FriendOneServlet.java類增加initSafetyConf安全初始化配置方法privatevoidinitSafetyConf(){Constans.CROSS_DOMAIN_STR.clear();StringcrossDomainStr=getServletContext().getInitParameter("CROSS_DOMAIN_STR");String[]crossDomainAry=crossDomainStr.split(",");for(Strings:crossDomainAry){Constans.CROSS_DOMAIN_STR.add(s.trim());}Constans.LOGIN_ERROR_TIMES=getServletContext().getInitParameter("LOGIN_ERROR_TIMES");Constans.LOGIN_ERROR_LOCK_SECOND=getServletContext().getInitParameter("LOGIN_ERROR_LOCK_SECOND");(Constans.CROSS_DOMAIN_STR);("LOGIN_ERROR_TIMES="+Constans.LOGIN_ERROR_TIMES);("LOGIN_ERROR_LOCK_SECOND="+Constans.LOGIN_ERROR_LOCK_SECOND);}在init方法中直接調(diào)用在ActionFilter.java類中增加checkCrossDomain跨域特殊字符串檢查,并在doFilter中進(jìn)行判斷驗(yàn)證,如果存在特殊字符,則直接跳轉(zhuǎn)到登陸界面修改error.jsp,此處是用于處理返回的錯(cuò)誤信息目前是通過<html-el:errors/>標(biāo)簽方式加載錯(cuò)誤信息,此處可根據(jù)輸入的條件來進(jìn)行錯(cuò)誤注入,執(zhí)行js代碼,修改該當(dāng)如下:一、將此錯(cuò)誤標(biāo)簽通過textarea進(jìn)行包裝,錯(cuò)誤信息是以文本方式顯示,無法執(zhí)行,如下:<textareastyle="height:100%;width:95%;color:red"readonly=true><html-el:errors/></textarea>同時(shí)修改BaseWebAction.java類的processError方法,將sb.append(ste[i]).append("<br>");這段代碼改為sb.append(ste[i]).append("\n");二、無論返回什么錯(cuò)誤信息,此處只顯示“操作故障,請(qǐng)確認(rèn)操作是否合法或聯(lián)系管理員檢查!”鏈接注入(便于跨站請(qǐng)求偽造)URL00/callAction.do安全問題描述可能會(huì)勸說初級(jí)用戶提供諸如用戶名、密碼、信用卡號(hào)、社會(huì)保險(xiǎn)號(hào)等敏感信息可能會(huì)竊取或操縱客戶會(huì)話和cookie,它們可能用于模仿合法用戶,從而使黑客能夠以該用戶身份查看或變更用戶記錄以及執(zhí)行事務(wù)可能會(huì)在Web服務(wù)器上上載、修改或刪除Web頁(yè)面、腳本和文件攻擊方法“鏈接注入”是修改站點(diǎn)內(nèi)容的行為,其方式為將外部站點(diǎn)的URL嵌入其中,或?qū)⒂幸资芄舻恼军c(diǎn)中的腳本的URL嵌入其中。將URL嵌入易受攻擊的站點(diǎn)中,攻擊者便能夠以它為平臺(tái)來啟動(dòng)對(duì)其他站點(diǎn)的攻擊,以及攻擊這個(gè)易受攻擊的站點(diǎn)本身。在這些可能的攻擊中,有些需要用戶在攻擊期間登錄站點(diǎn)。攻擊者從這一易受攻擊的站點(diǎn)本身啟動(dòng)這些攻擊,成功的機(jī)會(huì)比較大,因?yàn)橛脩舻卿浀目赡苄愿蟆!版溄幼⑷搿甭┒词怯脩糨斎肭謇聿怀浞值慕Y(jié)果,清理結(jié)果會(huì)在稍后的站點(diǎn)響應(yīng)中返回給用戶。攻擊者能夠?qū)⑽kU(xiǎn)字符注入響應(yīng)中,便能夠嵌入U(xiǎn)RL及其他可能的內(nèi)容修改。以下是“鏈接注入”的示例(我們假設(shè)“”站點(diǎn)有一個(gè)用來問候用戶的參數(shù),稱為“name”)。下列請(qǐng)求:HTTP:///greet.asp?name=JohnSmith會(huì)生成下列響應(yīng):<HTML><BODY>Hello,JohnSmith.</BODY></HTML>然而,惡意的用戶可以發(fā)送下列請(qǐng)求:HTTP:///greet.asp?name=<IMGSRC="http://www.ANY-SITE.com/ANYSCRIPT.asp">這會(huì)返回下列響應(yīng):<HTML><BODY>Hello,<IMGSRC="http://www.ANY-SITE.com/ANY-SCRIPT.asp">.</BODY></HTML>2012-7-416:57:34149/187如該示例所示,這有可能導(dǎo)致用戶瀏覽器向幾乎是攻擊者所期待的任何站點(diǎn)發(fā)出自動(dòng)請(qǐng)求。因此,他可能利用這個(gè)“鏈接注入”漏洞來啟動(dòng)若干類型的攻擊:跨站點(diǎn)偽造請(qǐng)求:攻擊者可以讓用戶的瀏覽器向用戶目前登錄的站點(diǎn)發(fā)送請(qǐng)求,以及執(zhí)行用戶并不想執(zhí)行的操作。這些操作可能包括從站點(diǎn)中注銷,或修改用戶的概要文件、電子郵件地址,甚至是修改密碼,結(jié)果造成徹底的帳戶接管??缯军c(diǎn)腳本編制:任何“跨站點(diǎn)腳本編制”攻擊都開始自誘惑用戶單擊精心制作的URL,以便利用受害者站點(diǎn)中的漏洞。發(fā)送含有惡意鏈接的電子郵件,或創(chuàng)建一個(gè)Web站點(diǎn)來包含指向易受攻擊的站點(diǎn)的鏈接,通常可以做到這一點(diǎn)。當(dāng)采用“鏈接注入”漏洞時(shí),有可能在A站點(diǎn)中嵌入一個(gè)惡意的URL,當(dāng)單擊這個(gè)鏈接時(shí),便啟動(dòng)對(duì)B站點(diǎn)的“跨站點(diǎn)腳本編制”攻擊。網(wǎng)絡(luò)釣魚:攻擊者有可能注入指向類似受攻擊站點(diǎn)的惡意站點(diǎn)的鏈接。不小心的用戶可能單擊這個(gè)鏈接,但并不知道自己即將離開原始站點(diǎn)而瀏覽到惡意站點(diǎn)。之后,攻擊者便可以誘惑用戶重新登錄,然后獲取他的登錄憑證。安全規(guī)范要求通過驗(yàn)證用戶輸入未包含危險(xiǎn)字符,便可能防止惡意的用戶導(dǎo)致應(yīng)用程序執(zhí)行計(jì)劃外的任務(wù),例如:?jiǎn)?dòng)任意SQL查詢、嵌入將在客戶端執(zhí)行的Javascript代碼、運(yùn)行各種操作系統(tǒng)命令,等等。建議過濾出所有以下字符:[1]|(豎線符號(hào))[2]&(&符號(hào))[3];(分號(hào))[4]$(美元符號(hào))[5]%(百分比符號(hào))[6]@(at符號(hào))[7]'(單引號(hào))[8]"(引號(hào))[9]\'(反斜杠轉(zhuǎn)義單引號(hào))[10]\"(反斜杠轉(zhuǎn)義引號(hào))[11]<>(尖括號(hào))[12]()(括號(hào))[13]+(加號(hào))[14]CR(回車符,ASCII0x0d)[15]LF(換行,ASCII0x0a)[16],(逗號(hào))[17]\(反斜杠)以下部分描述各種問題、問題的修訂建議以及可能觸發(fā)這些問題的危險(xiǎn)字符:SQL注入和SQL盲注:A.確保用戶輸入的值和類型(如Integer、Date等)有效,且符合應(yīng)用程序預(yù)期。B.利用存儲(chǔ)過程,將數(shù)據(jù)訪問抽象化,讓用戶不直接訪問表或視圖。當(dāng)使用存儲(chǔ)過程時(shí),請(qǐng)利用ADO命令對(duì)象來實(shí)施它們,以強(qiáng)化變量類型。C.清理輸入以排除上下文更改符號(hào),例如:[1]'(單引號(hào))[2]"(引號(hào))[3]\'(反斜線轉(zhuǎn)義單引號(hào))[4]\"(反斜杠轉(zhuǎn)義引號(hào))[5])(結(jié)束括號(hào))[6];(分號(hào))2012-7-416:57:34150/187跨站點(diǎn)腳本編制:A.清理用戶輸入,并過濾出JavaScript代碼。我們建議您過濾下列字符:[1]<>(尖括號(hào))[2]"(引號(hào))[3]'(單引號(hào))[4]%(百分比符號(hào))[5];(分號(hào))[6]()(括號(hào))[7]&(&符號(hào))[8]+(加號(hào))B.如果要修訂<%00script>變體,請(qǐng)參閱MS文章821349C.對(duì)于UTF-7攻擊:[-]可能的話,建議您施行特定字符集編碼(使用'Content-Type'頭或<meta>標(biāo)記)。HTTP響應(yīng)分割:清理用戶輸入(至少是稍后嵌入在HTTP響應(yīng)中的輸入)。請(qǐng)確保輸入未包含惡意的字符,例如:[1]CR(回車符,ASCII0x0d)[2]LF(換行,ASCII0x0a)遠(yuǎn)程命令執(zhí)行:清理輸入以排除對(duì)執(zhí)行操作系統(tǒng)命令有意義的符號(hào),例如:[1]|(豎線符號(hào))[2]&(&符號(hào))[3];(分號(hào))執(zhí)行shell命令:A.絕不將未檢查的用戶輸入傳遞給eval()、open()、sysopen()、system()之類的Perl命令。B.確保輸入未包含惡意的字符,例如:[1]$(美元符號(hào))[2]%(百分比符號(hào))[3]@(at符號(hào))XPath注入:清理輸入以排除上下文更改符號(hào),例如:[1]'(單引號(hào))[2]"(引號(hào))等LDAP注入:A.使用正面驗(yàn)證。字母數(shù)字過濾(A..Z,a..z,0..9)適合大部分LDAP查詢。B.應(yīng)該過濾出或進(jìn)行轉(zhuǎn)義的特殊LDAP字符:[1]在字符串開頭的空格或“#”字符[2]在字符串結(jié)尾的空格字符[3],(逗號(hào))[4]+(加號(hào))[5]"(引號(hào))[6]\(反斜杠)[7]<>(尖括號(hào))[8];(分號(hào))[9]()(括號(hào))MX注入:應(yīng)該過濾出特殊MX字符:[1]CR(回車符,ASCII0x0d)[2]LF(換行,ASCII0x0a)記錄偽造:應(yīng)該過濾出特殊記錄字符:[1]CR(回車符,ASCII0x0d)[2]LF(換行,ASCII0x0a)[3]BS(退格,ASCII0x08)ORM注入:A.確保用戶輸入的值和類型(如Integer、Date等)有效,且符合應(yīng)用程序預(yù)期。2012-7-416:57:34151/187B.利用存儲(chǔ)過程,將數(shù)據(jù)訪問抽象化,讓用戶不直接訪問表或視圖。C.使用參數(shù)化查詢APID.清理輸入以排除上下文更改符號(hào),例如:(*):[1]'(單引號(hào))[2]"(引號(hào))[3]\'(反斜線轉(zhuǎn)義單引號(hào))[4]\"(反斜杠轉(zhuǎn)義引號(hào))[5])(結(jié)束括號(hào))[6];(分號(hào))(*)這適用于SQL。高級(jí)查詢語(yǔ)言可能需要不同的清理機(jī)制。解決方案LoginImpl.java類中的getLoginInfo方法,將之前的操作員工號(hào)與密碼拼接方式改成SQL變量綁定方式StringBuffersqlbuf=newStringBuffer();sqlbuf.append("SELECT.orgcode,A.userid,A.username,A.password,A.validate,A.usertype,C.orgname,C.norgcode,C.orgtype,");sqlbuf.append("now()ASlogindate,sp_genseqfunc('S','D')ASsessionid,");sqlbuf.append("(SELECTGROUP_CONCAT(B.datatype)FROMtb_userdatarelBWHEREB.userid=?)ASdatatypes,PASSWORD(?)=A.passwordASpwdiscorrect");sqlbuf.append("FROMtb_userA,tb_organizationC");sqlbuf.append("WHEREA.userid=?ANDA.effdate<=CURDATE()ANDA.expdate>=CURDATE()ANDC.orgcode=A.orgcode");web.xml增加如下配置:<!--可能存在的跨域代碼字符串,用逗號(hào)分開--><context-param><param-name>CROSS_DOMAIN_STR</param-name><param-value><,>,%3C,%3E</param-value></context-param>Constans.java類增加如下變量:/***跨域特殊字符判斷*/publicstaticList<String>CROSS_DOMAIN_STR=newArrayList<String>();FriendOneServlet.java類增加initSafetyConf安全初始化配置方法privatevoidinitSafetyConf(){Constans.CROSS_DOMAIN_STR.clear();StringcrossDomainStr=getServletContext().getInitParameter("CROSS_DOMAIN_STR");String[]crossDomainAry=crossDomainStr.split(",");for(Strings:crossDomainAry){Constans.CROSS_DOMAIN_STR.add(s.trim());}Constans.LOGIN_ERROR_TIMES=getServletContext().getInitParameter("LOGIN_ERROR_TIMES");Constans.LOGIN_ERROR_LOCK_SECOND=getServletContext().getInitParameter("LOGIN_ERROR_LOCK_SECOND");(Constans.CROSS_DOMAIN_STR);("LOGIN_ERROR_TIMES="+Constans.LOGIN_ERROR_TIMES);("LOGIN_ERROR_LOCK_SECOND="+Constans.LOGIN_ERROR_LOCK_SECOND);}在init方法中直接調(diào)用在ActionFilter.java類中增加checkCrossDomain跨域特殊字符串檢查,并在doFilter中進(jìn)行判斷驗(yàn)證,如果存在特殊字符,則直接跳轉(zhuǎn)到登陸界面修改error.jsp,此處是用于處理返回的錯(cuò)誤信息目前是通過<html-el:errors/>標(biāo)簽方式加載錯(cuò)誤信息,此處可根據(jù)輸入的條件來進(jìn)行錯(cuò)誤注入,執(zhí)行js代碼,修改該當(dāng)如下:一、將此錯(cuò)誤標(biāo)簽通過textarea進(jìn)行包裝,錯(cuò)誤信息是以文本方式顯示,無法執(zhí)行,如下:<textareastyle="height:100%;width:95%;color:red"readonly=true><html-el:errors/></textarea>同時(shí)修改BaseWebAction.java類的processError方法,將sb.append(ste[i]).append("<br>");這段代碼改為sb.append(ste[i]).append("\n");二、無論返回什么錯(cuò)誤信息,此處只顯示“操作故障,請(qǐng)確認(rèn)操作是否合法或聯(lián)系管理員檢查!”應(yīng)用程序錯(cuò)誤URL00/callAction.do 00/clientAction.do 00/loginAction.do安全問題描述未對(duì)入局參數(shù)值執(zhí)行適當(dāng)?shù)倪吔鐧z查未執(zhí)行驗(yàn)證以確保用戶輸入與預(yù)期的數(shù)據(jù)類型匹配攻擊方法如果攻擊者通過偽造包含非應(yīng)用程序預(yù)期的參數(shù)或參數(shù)值的請(qǐng)求,來探測(cè)應(yīng)用程序(如以下示例所示),那么應(yīng)用程序可能會(huì)進(jìn)入易受攻擊的未定義狀態(tài)。攻擊者可以從應(yīng)用程序?qū)υ撜?qǐng)求的響應(yīng)中獲取有用的信息,且可利用該信息,以找出應(yīng)用程序的弱點(diǎn)。例如,如果參數(shù)字段是單引號(hào)括起來的字符串(如在ASP腳本或SQL查詢中),那么注入的單引號(hào)將會(huì)提前終止字符串流,從而更改腳本的正常流程/語(yǔ)法。錯(cuò)誤消息中泄露重要信息的另一個(gè)原因,是腳本編制引擎、Web服務(wù)器或數(shù)據(jù)庫(kù)配置錯(cuò)誤。以下是一些不同的變體:[1]除去參數(shù)[2]除去參數(shù)值[3]將參數(shù)值設(shè)置為空值[4]將參數(shù)值設(shè)置為數(shù)字溢出(+/-99999999)[5]將參數(shù)值設(shè)置為危險(xiǎn)字符,如'"\'\");[6]將某字符串附加到數(shù)字參數(shù)值安全規(guī)范要求所有涉及到拼接SQL的地方,用綁定變量方式解決方案非模糊匹配的很好改,將以前拼接的形式找成“?”號(hào),如果是動(dòng)態(tài)拼接,無法確定數(shù)量的,如通過如下形式:List<String>args=newArrayList<String>();if(!"".equals(order.getOrdertitle())){sql.append("anda.ordertitlelike?");args.add("%"+order.getOrdertitle()+"%");//這種方式是用來進(jìn)行模糊匹配的}if(!"".equals(order.getDbuser())){sql.append("anda.dbuser=?");args.add(order.getDbuser());}if(!"".equals(order.getEffdate())){sql.append("anda.effdate>=to_date(?,'yyyy-mm-dd')");//日期格式args.add(order.getEffdate());}if(!"".equals(order.getExpdate())){sql.append("anda.expdate<=to_date(?,'yyyy-mm-dd')");args.add(order.getExpdate());}拼接后查詢?nèi)缦拢篠tringsqlexec=pages.wrapSqlTotal(sql.toString(),getSimpleJdbcTemplate(),args.toArray());還有一種命名參數(shù)變量綁定的形式:Stringsql="SELECT*FROMtb_oa_fileswhereid=:id";List<FileInfo>files=newjava.util.ArrayList<FileInfo>();Map<String,String>parameters=newHashMap<String,String>();parameters.put("id",id);這種在查詢時(shí)傳入的是Map(key、value的鍵值對(duì)),key的值必需與綁定變量的名稱一致,查詢?nèi)缦拢篻etSimpleJdbcTemplate().query(sql,tb_oa_files_map,parameters);SQL查詢條件中帶In條件的變量綁定方法:如這種:selectdsnamefromtb_da_datasourcewheredsidin('111','222')首先我們確定從前臺(tái)傳過來的ID必需是不帶單引號(hào)括起來的,如上面這種,傳過來用逗號(hào)分開應(yīng)該是:111,222這種形式,在進(jìn)行變量綁定拼接SQL時(shí)進(jìn)行如下操作:StringBuffersql=newStringBuffer(“selectdsnamefromtb_da_datasourcewheredsidin(”);String[]idAry=ids.split(“,”);for(inti=0;i<idAry.length;i++){ if(i!=0) sql.append(“,”); sql.append(“?”);}sql.append(“)”);getSimpleJdbcTemplate().query(sql.toString(),map,idAry);如果查詢的變量不止這些ID還有其它的值,可通過下面方式:List<String>args=newArrayList<String>();if(!"".equals(dsname)){sql.append("anddsnamelike?");args.add("%"+dsname+"%");//這種方式是用來進(jìn)行模糊匹配的}String[]idAry=ids.split(“,”);for(inti=0;i<idAry.length;i++){ if(i!=0) sql.append(“,”); sql.append(“?”); args.add(idAry[i]);}sql.append(“)”);getSimpleJdbcTemplate().query(sql.toString(),map,args.toArray());重新初始化一個(gè)ArrayList(此種List是順序存儲(chǔ)結(jié)構(gòu),此止必需是順序存儲(chǔ)結(jié)構(gòu)),將數(shù)組的字增加到List,再通過toArray轉(zhuǎn)成數(shù)組。SQL查詢條件中帶In條件的命名參數(shù)的變量綁定。命名參數(shù)就是通過冒號(hào)+變量名的形式進(jìn)行綁定,在傳入?yún)?shù)時(shí)是一個(gè)key、value的鍵值對(duì),key必需與變量名保持一致,value就是對(duì)應(yīng)輸入的值。Map<String,String>parameters=newHashMap<String,String>();StringBuffersql=newStringBuffer(“selectdsnamefromtb_da_datasourcewheredsidin(”);String[]idAry=ids.split(“,”);for(inti=0;i<idAry.length;i++){ if(i!=0) sql.append(“,”); sql.append(“:dsid”).append(i);parameters.put(“dsid”+i,idAry[i]);}sql.append(“)”);getSimpleJdbcTemplate().query(sql.toString(),map,parameters);SQL注入U(xiǎn)RL00/loginAction.do安全問題描述可能會(huì)查看、修改或刪除數(shù)據(jù)庫(kù)條目和表攻擊方法Web應(yīng)用程序通常在后端使用數(shù)據(jù)庫(kù),以與企業(yè)數(shù)據(jù)倉(cāng)庫(kù)交互。查詢數(shù)據(jù)庫(kù)事實(shí)上的標(biāo)準(zhǔn)語(yǔ)言是SQL(各大數(shù)據(jù)庫(kù)供應(yīng)商都有自己的不同版本)。Web應(yīng)用程序通常會(huì)獲取用戶輸入(取自HTTP請(qǐng)求),將它并入SQL查詢中,然后發(fā)送到后端數(shù)據(jù)庫(kù)。接著應(yīng)用程序便處理查詢結(jié)果,有時(shí)會(huì)向用戶顯示結(jié)果。如果應(yīng)用程序?qū)τ脩簦ü粽撸┑妮斎胩幚聿粔蛐⌒模粽弑憧梢岳眠@種操作方式。在此情況下,攻擊者可以注入惡意的數(shù)據(jù),當(dāng)該數(shù)據(jù)并入SQL查詢中時(shí),就將查詢的原始語(yǔ)法更改得面目全非。例如,如果應(yīng)用程序使用用戶的輸入(如用戶名和密碼)來查詢用戶帳戶的數(shù)據(jù)庫(kù)表,以認(rèn)證用戶,而攻擊者能夠?qū)阂鈹?shù)據(jù)注入查詢的用戶名部分(和/或密碼部分),查詢便可能更改成完全不同的數(shù)據(jù)復(fù)制查詢,可能是修改數(shù)據(jù)庫(kù)的查詢,或在數(shù)據(jù)庫(kù)服務(wù)器上運(yùn)行Shell命令的查詢。一般而言,攻擊者會(huì)分步實(shí)現(xiàn)這個(gè)目標(biāo)。他會(huì)先學(xué)習(xí)SQL查詢的結(jié)構(gòu),然后使用該知識(shí)來阻撓查詢(通過注入更改查詢語(yǔ)法的數(shù)據(jù)),使執(zhí)行的查詢不同于預(yù)期。假設(shè)相關(guān)查詢是:SELECTCOUNT(*)FROMaccountsWHEREusername='$user'ANDpassword='$pass'其中$user和$pass是用戶輸入(從調(diào)用構(gòu)造查詢的腳本的HTTP請(qǐng)求收集而來-可能是來自GET請(qǐng)求查詢參數(shù),也可能是來自POST請(qǐng)求主體參數(shù))。此查詢的一般用法,其值為$user=john、$password=secret123。形成的查詢?nèi)缦拢篠ELECTCOUNT(*)FROMaccountsWHEREusername='john'ANDpassword='secret123'如果數(shù)據(jù)庫(kù)中沒有這個(gè)用戶密碼配對(duì),預(yù)期的查詢結(jié)果便是0,如果此類配對(duì)存在(也就是數(shù)據(jù)庫(kù)中有名稱為“john”的用戶,且其密碼為“secret123”),結(jié)果便是>0。這是應(yīng)用程序的基本認(rèn)證機(jī)制。但攻擊者可以用下列方式來更改此查詢:1.攻擊者可以提供單引號(hào)字符(')所組成的輸入,使數(shù)據(jù)庫(kù)發(fā)出錯(cuò)誤消息,其中通常包含關(guān)于SQL查詢的有價(jià)值的信息。攻擊者只需在發(fā)送的請(qǐng)求中包含用戶值',并在密碼中包含任何值(如foobar)。結(jié)果便是下列(格式錯(cuò)誤)的SQL查詢:SELECTCOUNT(*)FROMaccountsWHEREusername='''ANDpassword='foobar'這可能會(huì)產(chǎn)生以下錯(cuò)誤消息(取決于后端所使用的特定數(shù)據(jù)庫(kù)):查詢表達(dá)式'username='''ANDpassword='foobar''中發(fā)生語(yǔ)法錯(cuò)誤(遺漏運(yùn)算符)。2012-7-416:57:2971/187這時(shí)攻擊者便得知查詢是根據(jù)表達(dá)式username='$user'ANDpassword='$pass'來構(gòu)建的。利用手邊的SQL查詢時(shí)需要這一關(guān)鍵信息。攻擊者了解查詢的格式后,下一步只需使用:user='or1=1or''='password=foobar生成的查詢?nèi)缦拢篠ELECTCOUNT(*)FROMaccountsWHEREusername=''or1=1or''=''ANDpassword='foobar'這表示查詢(在SQL數(shù)據(jù)庫(kù)中)對(duì)于“accounts”表的每項(xiàng)記錄都會(huì)返回TRUE,因?yàn)?=1表達(dá)式永遠(yuǎn)為真。因此,查詢會(huì)返回“accounts”中的記錄數(shù)量,于是用戶(攻擊者)也會(huì)被視為有效。這個(gè)探測(cè)方法有若干變體,例如,發(fā)送';or\'(您應(yīng)該記住,幾乎所有供應(yīng)商都有他們自己唯一的SQL“版本”。具體地說,發(fā)送'having1=1,也會(huì)生成錯(cuò)誤消息,此消息會(huì)泄露有關(guān)列名稱的信息。在某些情況下,用戶輸入不會(huì)并入字符串上下文(用單引號(hào)括?。?,而是并入數(shù)字上下文,換言之,就是依現(xiàn)狀嵌入。因此,在這種情況下,可以使用輸入字符串
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 軟件設(shè)計(jì)師考試準(zhǔn)備工具試題及答案
- 政客與民意的博弈試題及答案
- 新興力量與西方傳統(tǒng)政治試題及答案
- 網(wǎng)絡(luò)工程師考試預(yù)測(cè)試題及答案
- 西方國(guó)家治理理念分析試題及答案
- 機(jī)電工程管理軟件應(yīng)用試題及答案2025
- 項(xiàng)目經(jīng)驗(yàn)總結(jié)及其價(jià)值試題及答案
- 2024年血容量擴(kuò)充劑資金籌措計(jì)劃書代可行性研究報(bào)告
- 機(jī)電工程2025年設(shè)備安裝試題及答案
- 跨界合作在軟件項(xiàng)目中的應(yīng)用與試題答案
- 濟(jì)南長(zhǎng)清產(chǎn)業(yè)發(fā)展投資控股集團(tuán)有限公司招聘筆試題庫(kù)2025
- 兒科脫水的分度及護(hù)理
- 讀書好相聲稿
- 三年級(jí)下冊(cè)科學(xué)期末測(cè)試卷【有一套】
- 超星爾雅學(xué)習(xí)通什么是科學(xué)(清華大學(xué))網(wǎng)課章節(jié)測(cè)試答案
- 【基于單片機(jī)的智能座椅避障系統(tǒng)設(shè)計(jì)開題報(bào)告文獻(xiàn)綜述4500字】
- 施工現(xiàn)場(chǎng)臨時(shí)用電安全技術(shù)規(guī)范
- GB/T 6317-1993帶表卡尺
- GB/T 4648-1996滾動(dòng)軸承圓錐滾子軸承凸緣外圈外形尺寸
- GB/T 34662-2017電氣設(shè)備可接觸熱表面的溫度指南
- 第6課 從隋唐盛世到五代十國(guó) 課件【高效備課+精講精研】高中歷史統(tǒng)編版(2019)必修中外歷史綱要上冊(cè)
評(píng)論
0/150
提交評(píng)論