文章出處:https://www.ibm.com/developerworks/cn/java/j-lo-audit-file-safe/index.html
文件路徑操縱、系統(tǒng)日志欺騙怎顾、線程安全和資源未釋放
葉 林, 張 東升, 和 賀 新朋2015 年 11 月 20 日發(fā)布
0
前言
本文是 JavaWeb 工程源代碼安全審計實戰(zhàn)的第 3 部分论矾,基于 WebGoat 工程,講解四種高危漏洞:文件路徑操縱杆勇、系統(tǒng)日志欺騙贪壳、線程安全和資源未釋放問題。重點討論的是源碼審計思路和攻防演練實戰(zhàn)蚜退。
Web 應(yīng)用威脅之文件路徑操縱
技術(shù)原理
當攻擊者可以指定文件名闰靴、文件路徑等文件操作的參數(shù)彪笼,就有可能越權(quán)訪問正常情況下無法到達的系統(tǒng)資源。
問題分析 PathBasedAccessControl.java129
源代碼審計發(fā)現(xiàn) PathBasedAccessControl.java 第 129 行 File() 方法蚂且。攻擊者有可能控制文件路徑越權(quán)訪問或者修改被保護的其他文件配猫。該文件內(nèi)容被作為頁面元素顯示。
圖 1. 問題代碼段
在已部署的 WebGoat 工程杏死,啟動生產(chǎn)環(huán)境泵肄。模擬攻擊者登錄,在左側(cè)導航目錄下點選“Access Control Flaws - Bypass a Path Based Access Control Scheme”, 任選一個 combox 中的 xx.html 文件淑翼,點擊“View Profile”提交腐巢。
攻擊場景
圖 2. 文件路徑操縱攻擊場景
解決方案
快速修復
解決 WebGoat 工程的示例的文件路徑操縱問題,可以在 PathBasedAccessControl.java 第 97 行方法玄括,添加對文件路徑的校驗冯丙。代碼片段如下:
圖 3. 整改文件路徑操縱的代碼
部署整改后的代碼,重新運行攻擊場景遭京,不可再現(xiàn)攻擊胃惜。
舉一反三
一般的,為防止文件路徑操縱問題哪雕,開發(fā)者首先要使用正確的系統(tǒng)函數(shù)船殉,其次可以自定義根據(jù)需要對文件操作參數(shù)進行過濾, 還可以利用服務(wù)器安全訪問框架斯嚎。提供以下五種思路:
- 使用規(guī)范路徑 getCanonicalPath()
攻擊者可以用包含 ../序列的參數(shù)來指定位于特定目錄之外的文件捺弦,從而違反程序安全策略,引發(fā)路徑遍歷漏洞孝扛,攻擊者可能向任意目錄上傳文件。
Java 語言對路徑的操作有 getAbsolutePath() 獲取絕對路徑和 getCannonicalPath() 獲取規(guī)范路徑幽崩。getCannonicalPath() 首先將路徑名轉(zhuǎn)換成絕對路徑名苦始,這與調(diào)用 getAbsolutePath() 方法的效果一樣。然后用與系統(tǒng)相關(guān)的方式將它映射到其惟一路徑名慌申。這通常涉及到從路徑名中移除多余的名稱(比如 "." 和 "..")陌选、分析符號連接(對于 UNIX 平臺),以及將驅(qū)動器名轉(zhuǎn)換成標準大小寫形式(對于 Microsoft Windows 平臺)蹄溉。所以應(yīng)該盡量使用規(guī)范路徑咨油,規(guī)避攻擊者可能使用的多余的分析符號。 - 開發(fā)者為使用到的文件操作參數(shù)進行輸入驗證柒爵,過濾字符(如“.”和“..”)
- 針對應(yīng)用場景役电,限制文件類型。比如使用的圖片文件只能是后綴.png, .jpg 而不可能是.bat, .sh棉胀。 建議加強對文件的判斷法瑟,要通過文件頭而不僅僅是文件后綴來判斷冀膝。
4.Java 安全管理器 permission Java.io.FilePermission - 服務(wù)器安全配置策略文件。能將所能讀取的文件限定在特定的目錄下霎挟。如何配置安全策略文件窝剖,和具體使用的服務(wù)器類型相關(guān)
Web 應(yīng)用威脅之系統(tǒng)日志 (Log) 欺騙和隱私泄露
當攻擊者有可能寫 Log 信息的時候,就有可能構(gòu)造虛假信息酥夭,迷惑 Log 讀者赐纱,迷惑系統(tǒng)運維調(diào)試人員調(diào)試系統(tǒng)故障。Log 欺騙可以協(xié)助攻擊者開展大型可持續(xù)攻擊 (APT)熬北。
源代碼審計發(fā)現(xiàn) HammerHead.java 第 271 行記錄未經(jīng)校驗的 message疙描,代碼片段如下:
圖 4. 問題代碼段
在已部署的 WebGoat 工程,啟動生產(chǎn)環(huán)境蒜埋。
模擬攻擊者登錄淫痰,在左側(cè)導航目錄下點選“Injection Flaws - Log Spoofing”, 在文本框輸入“Smith%0d%0aLogin Succeeded for username: admin”, 提交后假定服務(wù)器 Log 這段文本,將會在 Log 文件中新的一行中寫入虛假信息“Succeeded for username: admin”整份。攻擊的小竅門在換行符號\n待错,也就是轉(zhuǎn)碼后的 %0d%0a, 換行使 Log 中的欺騙信息看起來更真實。
WebGoat 的這個示例項目只是描述性展示烈评,沒有真正代碼執(zhí)行寫服務(wù)器日志火俄。
解決方案
- 換行符”\n”。Log 欺騙最關(guān)鍵的元素就是換行符讲冠,如果 Log 信息用黑名單過濾瓜客,”\n”一定要出現(xiàn)在黑名單中。如果 Log 信息用白名單過濾竿开,”\n”一定不能出現(xiàn)在白名單中
- 開發(fā)完成谱仪,在生產(chǎn)環(huán)境上線之前,要全部刪除 System.out()
- 分級 Log 開關(guān)否彩。軟件開發(fā)版本和發(fā)布版本疯攒,打開不同級別的 Log 開關(guān),清晰記錄的同時將危害降到最小范圍
- 控制 Log 內(nèi)容列荔。不以任何方式記錄用戶的敏感信息敬尺,哪怕是加密過的
- 不記錄隱私信息。當用戶隱私信息被寫到 Log 中時贴浙,就造成了隱私泄露砂吞。尤其是密碼信息,即使是加密之后的密碼信息崎溃,也不應(yīng)該被存儲到 Log 中蜻直。因為任何加密算法都有被破解的可能
WebGoat 工程演示了幾十個 Web 問題案例,比如上傳并執(zhí)行惡意文件等等。本文篇幅有限袭蝗,不一一列舉其他案例唤殴。
以上談?wù)摿?Web 高危漏洞的審計。下面講述幾個由于 Java 語言特性到腥,容易引導開發(fā)者犯下的編程錯誤朵逝。這些代碼缺陷使得工程不健壯,需要定點審計排查乡范、整改配名。
Java 和 JSP 代碼缺陷之線程安全
線程同步問題的本質(zhì)是全局共享靜態(tài)變量,導致同一線程下的兩個瀏覽器晋辆,互相影響對方渠脉。比如快速連續(xù)點擊 A,B 兩個不同瀏覽器端的提交按鈕。如果 B 對靜態(tài)變量的修改恰巧發(fā)生在 A 的對靜態(tài)變量的修改之后瓶佳、A 頁面回復內(nèi)容生成之前芋膘,那么 A 瀏覽器和共享全局變量相關(guān)的頁面內(nèi)容,可以被后提交的 B 瀏覽器頁面內(nèi)容所覆蓋霸饲。這違背了開發(fā)者的本意为朋。如果是電商網(wǎng)站,商品價格存在線程同步問題厚脉,可能導致 A 用戶用低廉的總價購買到昂貴商品习寸。
線程安全問題能隱藏的很深,一般單元測試無法發(fā)現(xiàn)傻工。因為程序在機器時間級別執(zhí)行霞溪,攻擊者難在切合的時間點打斷線程。但是如果設(shè)計高級攻擊場景中捆,先用拒絕服務(wù)攻擊 DDoS 消耗系統(tǒng)資源鸯匹,使得程序運行緩慢 (WebGoat 工程用 sleep 函數(shù)模擬),這時問題就凸顯了。線程安全問題亟需在安全開發(fā)和代碼審計階段被檢查到。
源代碼審計發(fā)現(xiàn) ThreadSafetyProblem.java 第 59 行定義靜態(tài)變量 currentUser宗侦,代碼段如下:
圖 5. 問題代碼段之定義靜態(tài)變量
ThreadSafetyProblem.java 第 92 行使用 currentUser 之前有 1.5 秒的休眠時間,這導致 currentUser 有可能被不同瀏覽器修改,進而得到違背開發(fā)者設(shè)想的污染數(shù)據(jù) results根蟹。
圖 6. 問題代碼段之 sleep
ThreadSafetyProblem.java 第 104 行是爆發(fā)點脓杉,使用被污染的 results 構(gòu)建頁面元素。
圖 7. 問題代碼段之爆發(fā)點
攻擊場景
部署 WebGoat 工程简逮,啟動生產(chǎn)環(huán)境球散。
開啟兩個瀏覽器 A 和 B. 在左側(cè)導航目錄下點選“Concurrency - Thread Safety Problems”。
A 瀏覽器輸入用戶名 Jeff散庶,提交蕉堰;
B 瀏覽器輸入用戶名 dave凌净,快速提交;
可見 A 的頁面內(nèi)容更新為 B 的 dave 表格屋讶。
解決方案
ThreadSafetyProblem.java 第 59 行注釋掉靜態(tài)變量冰寻,改為局部變量 currentUser,代碼段如下:
圖 8. 整改線程安全的代碼
以上整改代碼編譯部署后皿渗,WebGoat 生產(chǎn)環(huán)境的攻擊場景不再出現(xiàn)斩芭。
線程同步問題有很多對策,根據(jù)應(yīng)用場景乐疆,靈活采納以下方法: - 首先推薦將變量定義為局部變量划乖,而不是全局靜態(tài)變量。
2.Java 語言本身對線程提供了原生支持 synchronized挤土,通過同步一塊代碼或整個方法能夠保證同時最多只有單個線程執(zhí)行它琴庵,從而實現(xiàn)了線程安全。引入同步具有副作用仰美,即阻塞迷殿。開發(fā)者應(yīng)盡量避免使用同步。無論是 synchronized 關(guān)鍵字筒占,還是那些同步類(Hashtable 或 Vector)贪庙,應(yīng)盡量避免使用。 - 歷史上曾經(jīng)使用 JSP/Servlet 提供的 isThreadSafe 屬性/SingleThreadModel 接口解決全局變量線程安全問題翰苫。SingleThreadModel 不能解決所有的線程安全問題止邮。即便使用了 SingleThreadModel,會話 (session) 屬性仍然可以被多線程的請求同時訪問奏窑。SingleThreadModel 每個 Thread 都有自己的實例导披,比較消耗內(nèi)存資源。Servlet API 2.4 版本不推薦使用 SingleThreadModel 接口埃唯。
- 如果 Java Web 使用了框架撩匕,可以通過配置框架達到線程安全。如果使用 Struts2 框架墨叛,它的默認實現(xiàn)模式是 Prototype, 對每個請求 (request) 都新生成一個 Action 實例止毕,所以這里不存在全局變量引起的線程安全問題。如果不僅僅用到 Struts2漠趁,而是 Spring + Struts2扁凛,用 Spring 去管理 Struts2 的 Action,那么要注意 Spring 默認使用的是單例模式闯传,要修改 Spring 配置文件的 Scope 為 Prototype谨朝。
Java 和 JSP 代碼缺陷之資源未釋放
WebGoat 工程,用 Fortify 工具掃描共發(fā)現(xiàn) 196 個資源未釋放問題,其中 175 個數(shù)據(jù)庫連接資源未釋放問題字币,21 個流文件資源未釋放则披。
一般而言,Java 語言的 JVM 的垃圾自動回收機制能處理很多資源釋放問題洗出,但是也會帶來性能方面的負擔士复,帶來 DDoS 隱患。所以建議開發(fā)者主動釋放不再使用的資源共苛,而不是全盤依賴 JVM判没。
源代碼審計發(fā)現(xiàn) DOS_Login.java 第 104 行 createContent() 方法得到的 statement 沒有顯式釋放,這導致第 96 行 getConnection() 的系統(tǒng)資源被鎖定隅茎。代碼片段如下
圖 9. 問題代碼段
[圖片上傳中澄峰。。辟犀。(10)]點擊查看大圖
攻擊場景:WebGoat 雖然沒有對資源釋放漏洞的示例工程俏竞,容易理解通過這個漏洞能進行 DDoS 拒絕服務(wù)攻擊。
解決方案
在 finalize() 方法中顯式釋放 statement 代碼段形如:
finally {
if ( null != statement) {
safeClose(statement);}
}
其他代碼缺陷:源代碼掃描還能發(fā)現(xiàn) WebGoat 工程幾十個代碼缺陷(實際報告上百個代碼缺陷問題堂竟,有些是交叉引用)魂毁,硬編碼,弱加密等等出嘹。理解和整改比較直白席楚。篇幅有限,不一一列舉税稼。
結(jié)束語
本文是 JavaWeb 工程源代碼安全審計實戰(zhàn)的第 3 部分烦秩,主要針對文件路徑操縱、系統(tǒng)日志欺騙郎仆、線程安全和資源未釋放只祠,講解審計邏輯,用 WebGoat 工程實現(xiàn)攻防演練扰肌。JavaWeb 工程源代碼安全審計實戰(zhàn)的第四部分抛寝,將審計生產(chǎn)環(huán)境部署配置問題,歡迎閱讀曙旭。
文件路徑操縱盗舰、系統(tǒng)日志欺騙、線程安全和資源未釋放
葉 林, 張 東升, 和 賀 新朋2015 年 11 月 20 日發(fā)布
0
前言
本文是 JavaWeb 工程源代碼安全審計實戰(zhàn)的第 3 部分桂躏,基于 WebGoat 工程钻趋,講解四種高危漏洞:文件路徑操縱、系統(tǒng)日志欺騙沼头、線程安全和資源未釋放問題爷绘。重點討論的是源碼審計思路和攻防演練實戰(zhàn)。
Web 應(yīng)用威脅之文件路徑操縱
技術(shù)原理
當攻擊者可以指定文件名进倍、文件路徑等文件操作的參數(shù)土至,就有可能越權(quán)訪問正常情況下無法到達的系統(tǒng)資源。
問題分析 PathBasedAccessControl.java129
源代碼審計發(fā)現(xiàn) PathBasedAccessControl.java 第 129 行 File() 方法猾昆。攻擊者有可能控制文件路徑越權(quán)訪問或者修改被保護的其他文件陶因。該文件內(nèi)容被作為頁面元素顯示。
圖 1. 問題代碼段
在已部署的 WebGoat 工程垂蜗,啟動生產(chǎn)環(huán)境楷扬。模擬攻擊者登錄,在左側(cè)導航目錄下點選“Access Control Flaws - Bypass a Path Based Access Control Scheme”, 任選一個 combox 中的 xx.html 文件贴见,點擊“View Profile”提交烘苹。
攻擊場景
圖 2. 文件路徑操縱攻擊場景
解決方案
快速修復
解決 WebGoat 工程的示例的文件路徑操縱問題,可以在 PathBasedAccessControl.java 第 97 行方法片部,添加對文件路徑的校驗镣衡。代碼片段如下:
圖 3. 整改文件路徑操縱的代碼
部署整改后的代碼,重新運行攻擊場景档悠,不可再現(xiàn)攻擊廊鸥。
舉一反三
一般的,為防止文件路徑操縱問題辖所,開發(fā)者首先要使用正確的系統(tǒng)函數(shù)惰说,其次可以自定義根據(jù)需要對文件操作參數(shù)進行過濾, 還可以利用服務(wù)器安全訪問框架缘回。提供以下五種思路:
- 使用規(guī)范路徑 getCanonicalPath()
攻擊者可以用包含 ../序列的參數(shù)來指定位于特定目錄之外的文件吆视,從而違反程序安全策略,引發(fā)路徑遍歷漏洞切诀,攻擊者可能向任意目錄上傳文件揩环。
Java 語言對路徑的操作有 getAbsolutePath() 獲取絕對路徑和 getCannonicalPath() 獲取規(guī)范路徑。getCannonicalPath() 首先將路徑名轉(zhuǎn)換成絕對路徑名幅虑,這與調(diào)用 getAbsolutePath() 方法的效果一樣丰滑。然后用與系統(tǒng)相關(guān)的方式將它映射到其惟一路徑名。這通常涉及到從路徑名中移除多余的名稱(比如 "." 和 "..")倒庵、分析符號連接(對于 UNIX 平臺)褒墨,以及將驅(qū)動器名轉(zhuǎn)換成標準大小寫形式(對于 Microsoft Windows 平臺)。所以應(yīng)該盡量使用規(guī)范路徑擎宝,規(guī)避攻擊者可能使用的多余的分析符號郁妈。 - 開發(fā)者為使用到的文件操作參數(shù)進行輸入驗證,過濾字符(如“.”和“..”)
- 針對應(yīng)用場景绍申,限制文件類型噩咪。比如使用的圖片文件只能是后綴.png, .jpg 而不可能是.bat, .sh顾彰。 建議加強對文件的判斷,要通過文件頭而不僅僅是文件后綴來判斷胃碾。
4.Java 安全管理器 permission Java.io.FilePermission - 服務(wù)器安全配置策略文件涨享。能將所能讀取的文件限定在特定的目錄下。如何配置安全策略文件仆百,和具體使用的服務(wù)器類型相關(guān)
Web 應(yīng)用威脅之系統(tǒng)日志 (Log) 欺騙和隱私泄露
當攻擊者有可能寫 Log 信息的時候厕隧,就有可能構(gòu)造虛假信息,迷惑 Log 讀者俄周,迷惑系統(tǒng)運維調(diào)試人員調(diào)試系統(tǒng)故障吁讨。Log 欺騙可以協(xié)助攻擊者開展大型可持續(xù)攻擊 (APT)。
源代碼審計發(fā)現(xiàn) HammerHead.java 第 271 行記錄未經(jīng)校驗的 message峦朗,代碼片段如下:
圖 4. 問題代碼段
在已部署的 WebGoat 工程建丧,啟動生產(chǎn)環(huán)境。
模擬攻擊者登錄波势,在左側(cè)導航目錄下點選“Injection Flaws - Log Spoofing”, 在文本框輸入“Smith%0d%0aLogin Succeeded for username: admin”, 提交后假定服務(wù)器 Log 這段文本茶鹃,將會在 Log 文件中新的一行中寫入虛假信息“Succeeded for username: admin”。攻擊的小竅門在換行符號\n艰亮,也就是轉(zhuǎn)碼后的 %0d%0a, 換行使 Log 中的欺騙信息看起來更真實闭翩。
WebGoat 的這個示例項目只是描述性展示,沒有真正代碼執(zhí)行寫服務(wù)器日志迄埃。
解決方案
- 換行符”\n”疗韵。Log 欺騙最關(guān)鍵的元素就是換行符,如果 Log 信息用黑名單過濾侄非,”\n”一定要出現(xiàn)在黑名單中蕉汪。如果 Log 信息用白名單過濾,”\n”一定不能出現(xiàn)在白名單中
- 開發(fā)完成逞怨,在生產(chǎn)環(huán)境上線之前者疤,要全部刪除 System.out()
- 分級 Log 開關(guān)。軟件開發(fā)版本和發(fā)布版本叠赦,打開不同級別的 Log 開關(guān)驹马,清晰記錄的同時將危害降到最小范圍
- 控制 Log 內(nèi)容。不以任何方式記錄用戶的敏感信息除秀,哪怕是加密過的
- 不記錄隱私信息糯累。當用戶隱私信息被寫到 Log 中時,就造成了隱私泄露册踩。尤其是密碼信息泳姐,即使是加密之后的密碼信息,也不應(yīng)該被存儲到 Log 中暂吉。因為任何加密算法都有被破解的可能
WebGoat 工程演示了幾十個 Web 問題案例胖秒,比如上傳并執(zhí)行惡意文件等等缎患。本文篇幅有限,不一一列舉其他案例阎肝。
以上談?wù)摿?Web 高危漏洞的審計较锡。下面講述幾個由于 Java 語言特性,容易引導開發(fā)者犯下的編程錯誤盗痒。這些代碼缺陷使得工程不健壯,需要定點審計排查低散、整改俯邓。
Java 和 JSP 代碼缺陷之線程安全
線程同步問題的本質(zhì)是全局共享靜態(tài)變量,導致同一線程下的兩個瀏覽器熔号,互相影響對方稽鞭。比如快速連續(xù)點擊 A,B 兩個不同瀏覽器端的提交按鈕。如果 B 對靜態(tài)變量的修改恰巧發(fā)生在 A 的對靜態(tài)變量的修改之后引镊、A 頁面回復內(nèi)容生成之前朦蕴,那么 A 瀏覽器和共享全局變量相關(guān)的頁面內(nèi)容,可以被后提交的 B 瀏覽器頁面內(nèi)容所覆蓋弟头。這違背了開發(fā)者的本意吩抓。如果是電商網(wǎng)站,商品價格存在線程同步問題赴恨,可能導致 A 用戶用低廉的總價購買到昂貴商品疹娶。
線程安全問題能隱藏的很深,一般單元測試無法發(fā)現(xiàn)伦连。因為程序在機器時間級別執(zhí)行雨饺,攻擊者難在切合的時間點打斷線程。但是如果設(shè)計高級攻擊場景惑淳,先用拒絕服務(wù)攻擊 DDoS 消耗系統(tǒng)資源额港,使得程序運行緩慢 (WebGoat 工程用 sleep 函數(shù)模擬),這時問題就凸顯了歧焦。線程安全問題亟需在安全開發(fā)和代碼審計階段被檢查到移斩。
源代碼審計發(fā)現(xiàn) ThreadSafetyProblem.java 第 59 行定義靜態(tài)變量 currentUser,代碼段如下:
圖 5. 問題代碼段之定義靜態(tài)變量
ThreadSafetyProblem.java 第 92 行使用 currentUser 之前有 1.5 秒的休眠時間绢馍,這導致 currentUser 有可能被不同瀏覽器修改叹哭,進而得到違背開發(fā)者設(shè)想的污染數(shù)據(jù) results。
圖 6. 問題代碼段之 sleep
ThreadSafetyProblem.java 第 104 行是爆發(fā)點痕貌,使用被污染的 results 構(gòu)建頁面元素风罩。
圖 7. 問題代碼段之爆發(fā)點
攻擊場景
部署 WebGoat 工程,啟動生產(chǎn)環(huán)境舵稠。
開啟兩個瀏覽器 A 和 B. 在左側(cè)導航目錄下點選“Concurrency - Thread Safety Problems”超升。
A 瀏覽器輸入用戶名 Jeff入宦,提交;
B 瀏覽器輸入用戶名 dave室琢,快速提交乾闰;
可見 A 的頁面內(nèi)容更新為 B 的 dave 表格。
解決方案
ThreadSafetyProblem.java 第 59 行注釋掉靜態(tài)變量盈滴,改為局部變量 currentUser涯肩,代碼段如下:
圖 8. 整改線程安全的代碼
以上整改代碼編譯部署后,WebGoat 生產(chǎn)環(huán)境的攻擊場景不再出現(xiàn)巢钓。
線程同步問題有很多對策病苗,根據(jù)應(yīng)用場景,靈活采納以下方法: - 首先推薦將變量定義為局部變量症汹,而不是全局靜態(tài)變量硫朦。
2.Java 語言本身對線程提供了原生支持 synchronized,通過同步一塊代碼或整個方法能夠保證同時最多只有單個線程執(zhí)行它背镇,從而實現(xiàn)了線程安全咬展。引入同步具有副作用,即阻塞瞒斩。開發(fā)者應(yīng)盡量避免使用同步破婆。無論是 synchronized 關(guān)鍵字,還是那些同步類(Hashtable 或 Vector)胸囱,應(yīng)盡量避免使用荠割。 - 歷史上曾經(jīng)使用 JSP/Servlet 提供的 isThreadSafe 屬性/SingleThreadModel 接口解決全局變量線程安全問題。SingleThreadModel 不能解決所有的線程安全問題旺矾。即便使用了 SingleThreadModel蔑鹦,會話 (session) 屬性仍然可以被多線程的請求同時訪問。SingleThreadModel 每個 Thread 都有自己的實例箕宙,比較消耗內(nèi)存資源嚎朽。Servlet API 2.4 版本不推薦使用 SingleThreadModel 接口。
- 如果 Java Web 使用了框架柬帕,可以通過配置框架達到線程安全哟忍。如果使用 Struts2 框架,它的默認實現(xiàn)模式是 Prototype, 對每個請求 (request) 都新生成一個 Action 實例陷寝,所以這里不存在全局變量引起的線程安全問題锅很。如果不僅僅用到 Struts2,而是 Spring + Struts2凤跑,用 Spring 去管理 Struts2 的 Action爆安,那么要注意 Spring 默認使用的是單例模式,要修改 Spring 配置文件的 Scope 為 Prototype仔引。
Java 和 JSP 代碼缺陷之資源未釋放
WebGoat 工程扔仓,用 Fortify 工具掃描共發(fā)現(xiàn) 196 個資源未釋放問題褐奥,其中 175 個數(shù)據(jù)庫連接資源未釋放問題,21 個流文件資源未釋放翘簇。
一般而言撬码,Java 語言的 JVM 的垃圾自動回收機制能處理很多資源釋放問題,但是也會帶來性能方面的負擔版保,帶來 DDoS 隱患呜笑。所以建議開發(fā)者主動釋放不再使用的資源,而不是全盤依賴 JVM彻犁。
源代碼審計發(fā)現(xiàn) DOS_Login.java 第 104 行 createContent() 方法得到的 statement 沒有顯式釋放叫胁,這導致第 96 行 getConnection() 的系統(tǒng)資源被鎖定。代碼片段如下
圖 9. 問題代碼段
攻擊場景:WebGoat 雖然沒有對資源釋放漏洞的示例工程袖裕,容易理解通過這個漏洞能進行 DDoS 拒絕服務(wù)攻擊。
解決方案
在 finalize() 方法中顯式釋放 statement 代碼段形如:
finally {
if ( null != statement) {
safeClose(statement);}
}
其他代碼缺陷:源代碼掃描還能發(fā)現(xiàn) WebGoat 工程幾十個代碼缺陷(實際報告上百個代碼缺陷問題溉瓶,有些是交叉引用)急鳄,硬編碼,弱加密等等堰酿。理解和整改比較直白疾宏。篇幅有限,不一一列舉触创。
結(jié)束語
本文是 JavaWeb 工程源代碼安全審計實戰(zhàn)的第 3 部分坎藐,主要針對文件路徑操縱、系統(tǒng)日志欺騙哼绑、線程安全和資源未釋放岩馍,講解審計邏輯,用 WebGoat 工程實現(xiàn)攻防演練抖韩。JavaWeb 工程源代碼安全審計實戰(zhàn)的第四部分蛀恩,將審計生產(chǎn)環(huán)境部署配置問題,歡迎閱讀茂浮。