最近在做一些代碼安全性檢查,使用了Fortify。發(fā)現(xiàn)了一些曾經(jīng)引以為豪的代碼既然會(huì)出現(xiàn)高危的錯(cuò)誤。希望各位達(dá)人給予幫助。
設(shè)計(jì)初衷:共享WebApplicationContext,通過getBean(String beanName)取得對(duì)應(yīng)的bean處理相應(yīng)的業(yè)務(wù)邏輯。
public class BaseAction extends Action {
private WebApplicationContext wac;
protected ServletContext context;
public void setServlet(ActionServlet actionServlet) {
super.setServlet(actionServlet);
context = actionServlet.getServletContext();
wac = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
}

protected Object getBean(String beanName) {
return wac.getBean(beanName);
}
}
高危錯(cuò)誤代碼:
context = actionServlet.getServletContext();
wac = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
錯(cuò)誤原因分析:BaseAction繼承自Action,單例實(shí)現(xiàn)。該類含有屬性:wac與context,在多線程環(huán)境下不能保證這兩個(gè)屬性的合理邏輯。于是掉入了一個(gè)單例模式的陷阱。(請(qǐng)各位達(dá)人完善)
解決方法:jdon(banq)給我的回復(fù)
設(shè)計(jì)初衷:共享WebApplicationContext,通過getBean(String beanName)取得對(duì)應(yīng)的bean處理相應(yīng)的業(yè)務(wù)邏輯。
















解決方法:jdon(banq)給我的回復(fù)
banq:寫的方法是高危,但是看你的方法內(nèi)容,則沒有關(guān)系。 你的方法內(nèi)容是獲得一個(gè)Web項(xiàng)目的一個(gè)單例,實(shí)際就是Spring容器,而且大部分是讀,而不是讀寫并加。 單例陷阱我已經(jīng)在以前帖子中說了,只有在單例+寫+同步等操作下才可能死鎖,因?yàn)榇a不可控性,今天你注意沒這么做,不代表其他無知的人不這么做,所以,這種singlton會(huì)被嚴(yán)謹(jǐn)?shù)墓ぞ哒J(rèn)為是高危,這是正確的。 |
ME:謝謝 banq! 如果需要消除這段高危代碼,需要如何重構(gòu). 因?yàn)橹皇谴嬖谧x操作,我是否可以把wac與context定義為static(這樣工具不會(huì)報(bào)錯(cuò)) 請(qǐng)問這樣改會(huì)不會(huì)有問題? |
banq:不能用static,這樣Spring容器中所有資源都不能隨著你的WEB項(xiàng)目消失而消失。 主要問題在于你的setServlet(ActionServlet actionServlet)這個(gè)方法,這其實(shí)是一個(gè)初始化工作,試驗(yàn)在BaseAction的構(gòu)造方法中首先實(shí)現(xiàn),這樣表示有前有后,可能不會(huì)報(bào)高危錯(cuò)誤。 實(shí)在不行,做一個(gè)懶加載的方法,在這個(gè)方法中,檢查一下wac是否為空,如果為,就進(jìn)行初始化,不為空,就直接返回wac值。 |
去除setServlet方法,在getBean加入,如下,如果還不行,就每次老老實(shí)實(shí)的用WebApplicationContextUtils獲得Spring實(shí)例:![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |