Java Web 工程源代碼安全審計(jì)實(shí)戰(zhàn)瓶堕,第 1 部分

文章出處:https://www.ibm.com/developerworks/cn/java/j-lo-audit-xss/index.html
ava Web 工程源代碼安全審計(jì)實(shí)戰(zhàn)掠河,第 1 部分
跨站 XSS
葉 林, 張 東升, 和 賀 新朋2015 年 11 月 02 日發(fā)布

WeiboGoogle+用電子郵件發(fā)送本頁(yè)面


3

前言
Web 應(yīng)用是互聯(lián)網(wǎng)應(yīng)用的重要形式,是金融鸽凶、電信奏甫、政府部門等社會(huì)關(guān)鍵信息系統(tǒng)的門戶應(yīng)用首選。Web 應(yīng)用的組件技術(shù)和支撐手段不斷豐富變化症副。一般來(lái)講分為使用 Java 的店雅、使用 PHP 的和只使用 JavaScript 實(shí)現(xiàn)的三大類。其中的 Java Web 發(fā)展較早贞铣,所依托的 JEE 體系比較成熟闹啦,在企業(yè)級(jí)應(yīng)用中比較常見(jiàn)。其中的 PHP Web, 因?yàn)?PHP 開(kāi)發(fā)社區(qū)提供了很多優(yōu)秀的論壇網(wǎng)站框架辕坝,所以在論壇網(wǎng)站開(kāi)發(fā)中比較常用窍奋。而 JavaScript 通常用于瀏覽器的前端編程,近年其 Node.js 平臺(tái)提倡在服務(wù)器端和客戶端都使用 JavaScript酱畅,一時(shí)風(fēng)行琳袄。傳統(tǒng)的 Java Web 市場(chǎng)占有率較高,是本文討論的對(duì)象纺酸。
Web 應(yīng)用安全不容小覷窖逗。黑客對(duì)于 Web 應(yīng)用的攻擊熱點(diǎn),從早年的針對(duì)服務(wù)器系統(tǒng)平臺(tái)餐蔬,轉(zhuǎn)到針對(duì)瀏覽器滑负。因?yàn)閷ふ曳?wù)器上漏洞成本高在张,越來(lái)越難;而瀏覽器或者客戶端的攻擊技術(shù)矮慕,比如 SQL 注入、 跨站腳本 (XSS) 等技術(shù)門檻低啄骇,攻擊成本低痴鳄,相對(duì)容易實(shí)現(xiàn),已顯泛濫之勢(shì)缸夹。WAP 防火墻雖然能根據(jù)內(nèi)容過(guò)濾一些網(wǎng)絡(luò)流量痪寻,但是如果所有進(jìn)出的網(wǎng)絡(luò)流量都需要在應(yīng)用層上進(jìn)行檢測(cè),系統(tǒng)性能和成本付出較大虽惭。對(duì)服務(wù)器配置 HTTPS橡类,加密客戶端和服務(wù)器之間的 HTTP 內(nèi)容,雖然能保護(hù)信息隱私芽唇,但是還不足以單獨(dú)對(duì)抗除了數(shù)據(jù)竊聽(tīng)之外的種類繁多的 Web 攻擊顾画。
提高 Web 信息系統(tǒng)的安全性一個(gè)有效手段是對(duì)系統(tǒng)源代碼進(jìn)行靜態(tài)掃描。這樣可以在系統(tǒng)代碼上線匆笤、問(wèn)題發(fā)生之前研侣,檢查系統(tǒng)可能存在的安全風(fēng)險(xiǎn),防微杜漸炮捧,及時(shí)整改庶诡。
源代碼審計(jì)是一個(gè)系統(tǒng)工作。針對(duì) Java Web 的靜態(tài)掃描工具很多咆课,商用工具 Fortify 或者開(kāi)源工具 Findbugs末誓。各種工具并不健全,不同工具都具有不重復(fù)的功能书蚪,可以進(jìn)行多種工具配合使用以獲得更大的檢驗(yàn)覆蓋程度喇澡。同時(shí),這些分析工具們產(chǎn)生的結(jié)果有可能包含誤判或者漏判善炫。這時(shí)還需要人工審計(jì)撩幽。開(kāi)發(fā)人員要經(jīng)過(guò)安全開(kāi)發(fā)的訓(xùn)練,安全審計(jì)人員要經(jīng)過(guò)審計(jì)訓(xùn)練箩艺,才能熟練掌握 Java Web 源代碼安全審計(jì)方法窜醉。
“JavaWeb 工程源代碼安全審計(jì)實(shí)戰(zhàn)”系列基于著名的 Web 應(yīng)用安全研究組織 OWASP 維護(hù)的 Java Web 開(kāi)源項(xiàng)目 WebGoat,實(shí)戰(zhàn)演練對(duì)整體工程的安全審計(jì)艺谆。按照漏洞嚴(yán)重從高到低程度榨惰,抽取幾個(gè)審計(jì)結(jié)果展示。通過(guò)該系列可以了解以下幾種高危漏洞的審計(jì)思路:跨站静汤、SQL 注入琅催、文件路徑操縱和系統(tǒng)日志欺騙居凶。
本文是 JavaWeb 工程源代碼安全審計(jì)實(shí)戰(zhàn)的第一部分,主要針對(duì)跨站攻擊藤抡,講解審計(jì)邏輯侠碧,用 WebGoat 工程實(shí)現(xiàn)攻防演練。
源代碼審計(jì)概述
安全審計(jì)人員分析重點(diǎn)和思路都是圍繞尋找 Source 和 Sink 展開(kāi)缠黍。Source 是污染源弄兜,有害數(shù)據(jù)的入口點(diǎn)。Sink 是程序執(zhí)行造成危害爆發(fā)部分瓷式。面對(duì)一個(gè) Java Web 源碼工程替饿,審計(jì)人員:1)首先要在掃描工具的幫助下,初步了解所有的 Source(有文獻(xiàn)也叫 Taint) 和 Sink贸典;2)接下來(lái)追蹤污染路徑视卢,確定 Source–Path–Sink ,邏輯再現(xiàn)攻擊廊驼,避免工具的漏報(bào)誤報(bào)据过;3)如果條件允許,可以進(jìn)行漏洞利用開(kāi)發(fā)蔬充,Web 滲透測(cè)試蝶俱,真實(shí)攻擊;4)對(duì)于定位出的源碼漏洞饥漫,要提出整改意見(jiàn)榨呆;5)對(duì)修改后的源碼進(jìn)行二次審計(jì),避免整改副作用庸队。
工程目標(biāo)
對(duì) WebGoat 工程項(xiàng)目的源代碼進(jìn)行安全審核积蜻。WebGoat 是應(yīng)用安全研究組織 OWASP 精心設(shè)計(jì)并不斷更新的,專門設(shè)計(jì)用于展示各種 Web 漏洞的 Java Web 工程彻消。涉及語(yǔ)言為 Java 和 JSP竿拆,也包含部分 JavaScript。涉及文件包括這些編程語(yǔ)言源碼文件宾尚,也包括工程部署描述符和服務(wù)器運(yùn)行環(huán)境配置文件丙笋。
審核源代碼中的漏洞,包括能引發(fā)常見(jiàn) Web 應(yīng)用威脅的漏洞和基于語(yǔ)言缺陷的漏洞煌贴,并給出解決方案御板。審核環(huán)境配置文件,并給出安全加固建議牛郑。
漏洞類型
Web 應(yīng)用威脅
Web 攻擊和應(yīng)用威脅種類繁多怠肋。早年間攻擊者對(duì)服務(wù)器系統(tǒng)安置可執(zhí)行文件,通過(guò)本地訪問(wèn)或遠(yuǎn)程訪問(wèn)這些文件淹朋,達(dá)到控制服務(wù)器目的◇细鳎現(xiàn)在更傾向攻擊客戶端钉答,因?yàn)榧夹g(shù)門檻低,實(shí)施成本小杈抢。國(guó)際組織 OWASP 按危害程度排出前十名 Web 應(yīng)用安全威脅数尿,成為業(yè)內(nèi)標(biāo)桿參考。通過(guò)代碼審計(jì)發(fā)現(xiàn)程序薄弱點(diǎn)后惶楼,整改這些薄弱點(diǎn)砌创,可以對(duì)抗部分 Web 應(yīng)用威脅。
表 1.OWASP Top 10 2013
Web 應(yīng)用安全
威脅種類

威脅實(shí)施途徑

導(dǎo)致結(jié)果

A1. 注入
(SQL 注入鲫懒、OS 命令注入竖伯、XPATH 注入厚者、LDAP 注入、JSON 注入撬即、URL 注入)

頁(yè)面輸入宰缤,拼湊字符串颂翼,語(yǔ)句執(zhí)行

代碼邏輯依賴于外部輸入,可導(dǎo)致不可預(yù)期的行為

A2. 失效的身份認(rèn)證和會(huì)話管理

改變 cookie 內(nèi)容

扮演成為其他用戶身份

A3. 跨站腳本(XSS)

利用 URL 夾帶/附加 JavaScript 執(zhí)行腳本慨灭,嵌入木馬代碼

訪問(wèn)服務(wù)端敏感數(shù)據(jù)或者威脅客戶本地安全

A4. 不安全的直接對(duì)象引用

URL 參數(shù)解碼

猜測(cè) URL 對(duì)象內(nèi)容

A5. 安全配置錯(cuò)誤

修改權(quán)限配置文件

越權(quán)訪問(wèn)修改執(zhí)行朦乏,搗毀服務(wù)器或應(yīng)用程序

A6. 敏感數(shù)據(jù)暴露

各種

不可預(yù)料的問(wèn)題

A7. 功能級(jí)別訪問(wèn)控制缺失

文件路徑操縱

搗毀服務(wù)器或應(yīng)用程序

A8. 跨站請(qǐng)求偽造(CSRF)

誘騙點(diǎn)擊惡意 URL

扮演成為合法用戶身份

A9. 使用已知易受攻擊組件

使用第三方組件,不注意維護(hù)

不可預(yù)料的問(wèn)題

A10. 未驗(yàn)證的重定向和轉(zhuǎn)發(fā)

登錄頁(yè)面跳轉(zhuǎn)

用戶密碼泄露

Java 和 JSP 語(yǔ)言代碼缺陷
能工作的代碼并不代表好代碼氧骤。編程語(yǔ)言天然的代碼缺陷呻疹,易引導(dǎo)開(kāi)發(fā)者犯錯(cuò),造成程序不健壯筹陵,是代碼審計(jì)的靶點(diǎn)刽锤。
部署描述符和生產(chǎn)環(huán)境配置問(wèn)題
Java Web 應(yīng)用工程部署并運(yùn)行在服務(wù)器環(huán)境中,所以代碼安全審計(jì)除了檢查編程語(yǔ)言(Java, JSP朦佩,JavaScript)文件并思,還要檢查應(yīng)用和服務(wù)器的配置文件,對(duì)生產(chǎn)環(huán)境進(jìn)行安全加固语稠。
源代碼審核結(jié)果綜述
本次源代碼審計(jì)工作共檢查 WebGoat 工程代碼行數(shù) 39,422 行宋彼,包括 Java(34,349 行), JavaScript(632 行)和 JSP(4441 行)仙畦。
共發(fā)現(xiàn)累計(jì)上百個(gè)代碼缺陷输涕。其中接近一半高危缺陷。具體情況如下表所示议泵。
表 2. 源代碼審計(jì)結(jié)果綜述表


Web 應(yīng)用威脅之跨站 (XSS)
技術(shù)原理
WebGoat 工程源代碼有跨站的問(wèn)題占贫。跨站的本質(zhì)在于執(zhí)行腳本先口,讓受害者瀏覽器執(zhí)行攻擊者設(shè)計(jì)的 JavaScript/Flash/Html 等型奥。
跨站發(fā)生的條件有兩個(gè):1)來(lái)自不可信數(shù)據(jù)源的污染數(shù)據(jù)瞳收。在反射性跨站攻擊中,污染數(shù)據(jù)來(lái)自頁(yè)面請(qǐng)求厢汹。在存儲(chǔ)型跨站中螟深,污染數(shù)據(jù)來(lái)自服務(wù)器后臺(tái)數(shù)據(jù)庫(kù)。2)污染數(shù)據(jù)未經(jīng)檢驗(yàn)就被作為動(dòng)態(tài)內(nèi)容提交給用戶瀏覽器執(zhí)行烫葬。
問(wèn)題分析之反射跨站 ReflectedXSS.java:187
源代碼審計(jì)發(fā)現(xiàn) ReflectedXSS.java 第 187 行 addElement () 方法向?yàn)g覽器發(fā)送未經(jīng)驗(yàn)證的數(shù)據(jù)界弧,如果這個(gè)數(shù)據(jù)是來(lái)自攻擊者的 JavaScript 代碼,瀏覽器會(huì)執(zhí)行攻擊者命令搭综。
本例中垢箕,完成一次完整的污染傳播 Source-Path-Sink 三步驟如下:
ParameterParser.java 第 615 行使用 getParameterValues() 從網(wǎng)頁(yè) request 獲取數(shù)據(jù),代碼片段如下:
圖 1. 污染數(shù)據(jù)來(lái)自不可信任的數(shù)據(jù)源 (Source)

ReflectedXSS.java 第 597 行使用 getRawParameter() 傳播污染數(shù)據(jù)兑巾,代碼段如下:
圖 2. 污染數(shù)據(jù)在程序體內(nèi)部沿路徑傳播(Path)

ReflectedXSS.java 第 75 行使用來(lái)自污染源 field1 的數(shù)據(jù)對(duì) param1 賦值条获,并用 param1 構(gòu)造頁(yè)面元素,代碼段如下:
圖 3. 污染源 field1 對(duì) param1 賦值
點(diǎn)擊查看大圖

下圖來(lái)自 Fortify 分析工具蒋歌,紅色箭頭指示傳播路徑帅掘,右紫色框代表 Source,左紅色框代表 Sink堂油。
圖 4. 污染數(shù)據(jù)傳播路徑圖

點(diǎn)擊查看大圖

SqlStringInjection.java 第 187 行 addElement () 使用了來(lái)自不可信數(shù)據(jù)源的污染數(shù)據(jù)構(gòu)建頁(yè)面元素修档,代碼片段如下:
圖 5. 污染數(shù)據(jù)被用來(lái)構(gòu)造頁(yè)面元素 (Sink)

點(diǎn)擊查看大圖

至此污染源,路徑府框,爆發(fā)點(diǎn)(Source-Path-Sink)確定吱窝。注意到污染數(shù)據(jù)在傳播路徑上,沒(méi)有校驗(yàn)過(guò)濾過(guò)寓免,滿足技術(shù)原理中 XSS 攻擊條件:1) 來(lái)自不可信數(shù)據(jù)源的污染數(shù)據(jù)癣诱;2) 污染數(shù)據(jù)未經(jīng)檢驗(yàn)就被作為動(dòng)態(tài)內(nèi)容提交給用戶瀏覽器執(zhí)行。代碼審計(jì)邏輯上可以判斷這是一個(gè) XSS 漏洞袜香。
攻擊場(chǎng)景
在已部署的 WebGoat 工程撕予,啟動(dòng)生產(chǎn)環(huán)境(WebGoat 工程使用見(jiàn)附錄)。
在左側(cè)導(dǎo)航目錄下點(diǎn)選" Reflected XSS Attacks", 在右側(cè)頁(yè)面最下方的文本框 Enter your three digit access code:輸入<script>alert('Hacked.')</script>蜈首。
觀察彈框出現(xiàn)实抡。彈框腳本的成功執(zhí)行證明頁(yè)面存在跨站漏洞。
圖 6. 反射跨站攻擊場(chǎng)景


彈框腳本不具強(qiáng)大攻擊力欢策,但是其他惡意腳本可以作為系列高級(jí)可持續(xù)攻擊 (APT) 的組成部分吆寨。比如先誘騙受害者訪問(wèn)攻擊者構(gòu)造的 html 頁(yè)面元素 Image,而 Image.src 屬性要求瀏覽器訪問(wèn)某個(gè)地址 (URL)踩寇,該 URL 是惡意腳本讀取受害者當(dāng)前用戶頁(yè)面的 session啄清、cookie 等敏感信息并動(dòng)態(tài)拼接而成,形如 http://hacker.com&victomCookie=cookie俺孙。這些敏感信息被發(fā)送到攻擊者可控制的 URL辣卒,被攻擊者讀取掷贾。在金融操作中,用戶帳號(hào)荣茫、余額等敏感信息可以這樣被泄露想帅。
XSS 攻擊永遠(yuǎn)不止步于彈框、收集頁(yè)面 cookie 信息啡莉。XSS 的本質(zhì)在于瀏覽器端執(zhí)行腳本港准。有人甚至說(shuō) 覽 XSS is the New Buffer Overflow, JavaScript Malware is the new shell code”。這是類比傳統(tǒng)對(duì)服務(wù)器的攻擊手法:在服務(wù)器操作系統(tǒng)堆棧中用緩沖區(qū)溢出咧欣,改寫(xiě)程序返回地址的方法浅缸,把執(zhí)行程序引向執(zhí)行惡意代碼。這種傳統(tǒng)的針對(duì)服務(wù)器的攻擊實(shí)施門檻高魄咕。XSS 攻擊在受害者環(huán)境引導(dǎo)瀏覽器執(zhí)行惡意代碼疗杉。進(jìn)而通過(guò)攻擊用戶本地電腦其他服務(wù)〔侠瘢跨站攻擊實(shí)施門檻低,攻擊力強(qiáng)大梢什,需要認(rèn)真審計(jì)源碼奠蹬,規(guī)避 XSS 漏洞。
以上審計(jì)分析的反射跨站嗡午,污染數(shù)據(jù)直接來(lái)自受害者瀏覽器頁(yè)面請(qǐng)求 web request囤躁,攻擊要臨機(jī)操作,執(zhí)行有難度荔睹。下面審計(jì)分析存儲(chǔ)跨站狸演。存儲(chǔ)跨站的攻擊者和受害者使用各自現(xiàn)場(chǎng)瀏覽器,執(zhí)行攻擊相對(duì)容易僻他。
問(wèn)題分析之存儲(chǔ)跨站 StoredXSS.java:230
源代碼靜態(tài)掃描發(fā)現(xiàn) StoredXSS.java 第 230 行 makeCurrent() 方法向?yàn)g覽器發(fā)送未經(jīng)驗(yàn)證的數(shù)據(jù)宵距,如果這個(gè)數(shù)據(jù)是來(lái)自攻擊者的 JavaScript 代碼,瀏覽器會(huì)執(zhí)行攻擊者命令吨拗。本例中满哪,完成一次完整的污染傳播 Source-Path-Sink 三步驟如下:
StoredXss.java 第 218 行使用 executeQuery() 從數(shù)據(jù)庫(kù)讀取數(shù)據(jù),代碼片段如下:
圖 7. 污染數(shù)據(jù)來(lái)自不可信任的數(shù)據(jù)源 (Source)
點(diǎn)擊查看大圖

本案例數(shù)據(jù)庫(kù)是不可信任的數(shù)據(jù)源劝篷,因?yàn)檫M(jìn)一步分析數(shù)據(jù)庫(kù)發(fā)現(xiàn)數(shù)據(jù)來(lái)自未經(jīng)校驗(yàn)的網(wǎng)頁(yè)用戶輸入哨鸭。
更進(jìn)一步分析數(shù)據(jù)庫(kù)的數(shù)據(jù)來(lái)源:
ParameterParser.java 第 615 行使用 getParameterValues() 從網(wǎng)頁(yè) request 獲取數(shù)據(jù),代碼片段如下:
圖 8. 從網(wǎng)頁(yè)獲取數(shù)據(jù)


StoredXss.java 第 97 行執(zhí)行 getRawParameter() 從網(wǎng)頁(yè) request 獲取數(shù)據(jù)娇妓,付給 message像鸡。第 110 行執(zhí)行 execute(),向數(shù)據(jù)庫(kù)寫(xiě)入 message 哈恰。代碼片段如下:
圖 9. 向數(shù)據(jù)庫(kù)寫(xiě)數(shù)據(jù)
點(diǎn)擊查看大圖

觀察數(shù)據(jù)傳播過(guò)程只估,沒(méi)有對(duì)寫(xiě)入數(shù)據(jù)的校驗(yàn)過(guò)濾志群。
從數(shù)據(jù)庫(kù)中讀取到的污染數(shù)據(jù),在程序體內(nèi)流轉(zhuǎn)后到達(dá)爆發(fā)點(diǎn)仅乓,即紅色框代表的 Sink赖舟。下圖來(lái)自 Fortify 分析工具:
圖 10. 污染數(shù)據(jù)在程序體內(nèi)部沿路徑傳播(Path)


StoredXss.java 第 230 行 makeCurrent() 使用了來(lái)自不可信數(shù)據(jù)源的污染數(shù)據(jù) results,構(gòu)建頁(yè)面元素夸楣,代碼片段如下:
圖 11. 污染數(shù)據(jù)被用來(lái)構(gòu)造頁(yè)面元素 (Sink)

至此污染源宾抓,路徑,爆發(fā)點(diǎn)(Source-Path-Sink)確定豫喧。注意到污染數(shù)據(jù)在傳播路徑上石洗,沒(méi)有被校驗(yàn)過(guò)濾過(guò),滿足 XSS 攻擊的兩個(gè)條件:1) 來(lái)自不可信數(shù)據(jù)源的污染數(shù)據(jù)紧显。2) 污染數(shù)據(jù)未經(jīng)檢驗(yàn)就被作為動(dòng)態(tài)內(nèi)容提交給用戶瀏覽器執(zhí)行讲衫。所以代碼審計(jì)邏輯上可以判斷這是一個(gè) XSS 漏洞。被污染的數(shù)據(jù)存放在服務(wù)器數(shù)據(jù)庫(kù)中孵班。進(jìn)一步推斷這是存儲(chǔ)型 XSS 漏洞涉兽。
攻擊場(chǎng)景
在已部署的 WebGoat 工程,啟動(dòng)生產(chǎn)環(huán)境篙程。(WebGoat 工程使用見(jiàn)附錄)
模擬攻擊者登錄枷畏,在左側(cè)導(dǎo)航目錄下點(diǎn)選" Stored XSS Attacks", 在 Title 文本框輸入" anyTitle", 在 Message 文本框輸入"<script>alert('Hacked.')</script>"點(diǎn)擊提交按鈕。污染數(shù)據(jù)存入后臺(tái)數(shù)據(jù)庫(kù)虱饿。攻擊完成拥诡。
圖 12. 存儲(chǔ)跨站攻擊場(chǎng)景
點(diǎn)擊查看大圖

受害者啟動(dòng)一個(gè)新瀏覽器,在左側(cè)導(dǎo)航目錄下點(diǎn)選" Stored XSS Attacks", 在頁(yè)面上找到并點(diǎn)擊" anyTitle"字樣超鏈接氮发,觀察彈框出現(xiàn)渴肉。證明頁(yè)面存在執(zhí)行惡意腳本的能力。
解決方案
快速修復(fù)
解決 WebGoat 工程的反射跨站問(wèn)題爽冕,可以在 ReflectedXSS.java 第 75 行使用 WebGoat 自實(shí)現(xiàn)的 HtmlEncoder.encode() 對(duì)污染數(shù)據(jù)編碼處理后再輸出仇祭。代碼片段如下:
圖 13. 整改反射跨站的代碼

點(diǎn)擊查看大圖

類似的,解決 WebGoat 工程的存儲(chǔ)跨站問(wèn)題颈畸,可以在 StoredXSS.java 使用以下代碼片段:
圖 14. 整改存儲(chǔ)跨站的代碼


整改代碼編譯部署后前塔,WebGoat 生產(chǎn)環(huán)境的攻擊場(chǎng)景不再出現(xiàn)。
以上代碼的整改思路是”輸出編碼”承冰。對(duì)輸出到客戶端的字符串進(jìn)行編碼可以使系統(tǒng)更加安全华弓。
將“<”編碼為“<”,“"”編碼為“"”困乒,這樣”<script>”保存后最終存儲(chǔ)的會(huì)是:“<script&gt”寂屏;在展現(xiàn)時(shí)瀏覽器會(huì)對(duì)這些字符轉(zhuǎn)換成文本內(nèi)容<script>顯示,而不是去執(zhí)行一段可執(zhí)行的代碼。
除了“輸出編碼”迁霎,XSS 跨站的解決方法還有“輸入驗(yàn)證和數(shù)據(jù)凈化”吱抚。以下系統(tǒng)講解 XSS 各種解決方案。
舉一反三
XSS 跨站問(wèn)題的根本原因是對(duì)輸入?yún)?shù)處理不當(dāng)考廉。解決思路有兩條:“輸入驗(yàn)證數(shù)據(jù)凈化”和“輸出編碼”秘豹。
基于 HTTP 通信協(xié)議的 Web 應(yīng)用中,服務(wù)器先接收請(qǐng)求昌粤,再應(yīng)答請(qǐng)求把字符串輸出到客戶端既绕。對(duì) XSS 跨站的防范應(yīng)該部署在服務(wù)器輸入和輸出兩個(gè)階段。當(dāng)服務(wù)器接收輸入請(qǐng)求時(shí)涮坐,進(jìn)行數(shù)據(jù)驗(yàn)證和凈化凄贩。當(dāng)服務(wù)器輸出應(yīng)答請(qǐng)求時(shí),對(duì)應(yīng)答字符串進(jìn)行編碼袱讹∑T“輸入驗(yàn)證”和“輸出編碼”可以獨(dú)立實(shí)施,也可互為補(bǔ)充捷雕。
輸入驗(yàn)證和數(shù)據(jù)凈化
輸入驗(yàn)證和數(shù)據(jù)凈化一般使用過(guò)濾器椒丧,基于黑白名單進(jìn)行數(shù)據(jù)凈化。使用過(guò)濾器有三點(diǎn)需要注意救巷。

  1. 首先強(qiáng)調(diào)過(guò)濾要在服務(wù)器端進(jìn)行瓜挽,客戶端的驗(yàn)證容易被繞過(guò)。只要攻擊者用抓包工具捕獲從客戶端發(fā)送到服務(wù)器的報(bào)文征绸、修改并重放,就有可能攻擊成功俄占。在服務(wù)器端代碼已經(jīng)實(shí)施過(guò)濾的基礎(chǔ)上管怠,可以建議在客戶端也可以進(jìn)行過(guò)濾,多次過(guò)濾的目的是減少服務(wù)器的負(fù)荷缸榄。
  2. 其次要注意先標(biāo)準(zhǔn)化渤弛,然后再檢驗(yàn)字符串。
    因?yàn)椴煌姹?unicode 編碼集的不同甚带,所以同一個(gè)字符沒(méi)有唯一的二進(jìn)制表達(dá)她肯,存在二義性。比如尖括號(hào)<>鹰贵,在一種 unicode 版本中可能表達(dá)為“\uFE64” “\uFE65”, 在另外 unicode 版本可能表達(dá)為另外形式晴氨。
    通常用 NFKC 格式對(duì)任意編碼的字符串進(jìn)行標(biāo)準(zhǔn)化,消除二義性(當(dāng)然還有 NFKD 標(biāo)準(zhǔn)化形式碉输,總要選一種)籽前。代碼如下:
    String s =“\uFE64”+“script”+“\uFE65”;
    s = Normalizer.normalize(s, Form.NFKC);
    pattern.matcher(s)
  3. 還要注意過(guò)濾內(nèi)容必須充分。按照安全權(quán)限最小化的思想,盡量使用白名單枝哄。因?yàn)楹诿麊瘟信e有限肄梨,掛一漏百。白名單可以結(jié)合業(yè)務(wù)邏輯進(jìn)行編排挠锥,比如年齡字段只允許輸入數(shù)字众羡。如果業(yè)務(wù)邏輯不容易枚舉白名單,只能通過(guò)黑名單過(guò)濾蓖租,那么要保證過(guò)濾內(nèi)容的充分粱侣,一級(jí)防范至少要過(guò)濾掉“<”、“>”菜秦、“'”甜害、“"”和“\”五個(gè)特殊字符。代碼如下:
    Pattern patter = Pattern.compile(“<|>|’|”|\”)
    更深一步的防范可以考慮以下的內(nèi)容:
    過(guò)濾“<”球昨、“>”將用戶輸入放入引號(hào)間尔店,基本實(shí)現(xiàn)數(shù)據(jù)與代碼隔離;
    過(guò)濾雙引號(hào)主慰,防止用戶跨越許可的標(biāo)記嚣州,添加自定義標(biāo)記;
    過(guò)濾 TAB 和空格共螺,防止關(guān)鍵字被拆分该肴;
    過(guò)濾 script 關(guān)鍵字;
    過(guò)濾&# 防止 HTML 屬性繞過(guò)檢查藐不。
    4 過(guò)濾設(shè)計(jì)要綜合考量性能因素匀哄,選擇多次過(guò)濾或者單字符過(guò)濾。
    首先認(rèn)識(shí)到過(guò)濾的副作用雏蛮,英語(yǔ)語(yǔ)義可能破壞涎嚼,yours’ 會(huì)被過(guò)濾為 yours。其次有時(shí)需要多次過(guò)濾挑秉,例如<scrip<script>t>過(guò)濾掉<script>后還是<script>法梯。需要注意多個(gè)過(guò)濾器的先后次序。當(dāng)多個(gè)過(guò)濾器一起生效時(shí)犀概,有可能后進(jìn)行的過(guò)濾導(dǎo)致前面的過(guò)濾失效立哑。例如過(guò)濾器 1 要過(guò)濾 ABC,過(guò)濾器 2 要過(guò)濾 DEF姻灶,那么 ABDEFC 在依次通過(guò) 1铛绰,2 過(guò)濾器后變成了 ABC,這樣相當(dāng)于繞開(kāi)過(guò)濾器 1产喉。所以如果性能許可至耻,要單獨(dú)單字符過(guò)濾若皱。
    以上在服務(wù)器輸入端進(jìn)行整改。下面講述在服務(wù)器輸出端的整改方法尘颓。
    輸出編碼 (Html encode)
    以下三方法任選其一
  4. 開(kāi)發(fā)者自己實(shí)現(xiàn)編碼輸出走触,可以參考 WebGoat 工程源碼 HtmlEncoder.java,也可以簡(jiǎn)要實(shí)現(xiàn)如下:
    private String cleanXSS(String value) {
    value = value.replaceAll("<", "& lt;")疤苹;
    value=value.replaceAll(">", "& gt;");
    value = value.replaceAll("'", "& #39;");
    // to be augmented..
    return value;
    }
  5. 也可以使用 Apache 的 commons-lang.jar 提供系統(tǒng)庫(kù)函數(shù):
    StringEscapeUtils.escapeHtml(str);
    HTML 的輸出編碼是防止注入 XSS 的通用手法互广,除了 Java,其他語(yǔ)言都有提供對(duì) HTML 的輸出編碼:
    PHP 的 htmlentities() 或是 htmlspecialchars()卧土。
    Python 的 cgi.escape()惫皱。
    ASP 的 Server.HTMLEncode()。
    基于.net 開(kāi)發(fā)的 Web 應(yīng)用尤莺,系統(tǒng)庫(kù)函數(shù) AntiXss.HtmlEncode Java 的 xssprotect(Open Source Library)旅敷。
    Node.js 的 node-validator。
    3.WebGoat 是獨(dú)立實(shí)施的 Web 應(yīng)用颤霎。但是現(xiàn)實(shí) Web 應(yīng)用可以基于一些框架媳谁,比如 Spring Struts Hiberante。如果使用 Spring 框架進(jìn)行 Java Web 開(kāi)發(fā)友酱,可以在 web.xml 文件中設(shè)置 HTML encode晴音,在 JSP 文件頁(yè)面元素 form 中確定實(shí)施。
    web.xml 加上:
    <context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>true</param-value>
    </context-param>
    forms 加上:
    <spring:htmlEscape defaultHtmlEscape="true" />
    縱深防御
    除了通用的輸入驗(yàn)證和輸出編碼防御思路缔杉。有些特定的頁(yè)面元素锤躁,也有自己的防 XSS 屬性設(shè)置。
  6. 設(shè)置 cookie 的 HttpOnly 屬性
    XSS 通常被用于偷取 cookie 內(nèi)容或详。在設(shè)置 cookie 時(shí)使用 HttpOnly 參數(shù)系羞,限制 cookie 作為 DOM 對(duì)象存取。
  7. 設(shè)置<frame>的 security 屬性
    IE6 以后的版本提供<frame>和<iframe>新的 security 屬性霸琴,可以針對(duì)個(gè)別的 frame 或 iframe 設(shè)定 Restricted Sites椒振,在 Restricted Sites 區(qū)塊內(nèi)將不支持 scripts 語(yǔ)法的執(zhí)行。代碼片段如下:
    <frame security="restricted"src="//www.somesite.com/somepage.htm"></frame>
    結(jié)束語(yǔ)
    本文是 JavaWeb 工程源代碼安全審計(jì)實(shí)戰(zhàn)的第 1 部分沈贝,主要針對(duì)跨站攻擊,講解審計(jì)邏輯勋乾,用 WebGoat 工程實(shí)現(xiàn)攻防演練宋下。JavaWeb 工程源代碼安全審計(jì)實(shí)戰(zhàn)的第 2 部分,將審計(jì) SQL 注入攻擊辑莫,歡迎閱讀学歧。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市各吨,隨后出現(xiàn)的幾起案子枝笨,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件横浑,死亡現(xiàn)場(chǎng)離奇詭異剔桨,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)徙融,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門洒缀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人欺冀,你說(shuō)我怎么就攤上這事树绩。” “怎么了隐轩?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵饺饭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我职车,道長(zhǎng)瘫俊,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任提鸟,我火速辦了婚禮军援,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘称勋。我一直安慰自己胸哥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布赡鲜。 她就那樣靜靜地躺著空厌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪银酬。 梳的紋絲不亂的頭發(fā)上嘲更,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音揩瞪,去河邊找鬼赋朦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛李破,可吹牛的內(nèi)容都是我干的宠哄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼嗤攻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼毛嫉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起妇菱,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤承粤,失蹤者是張志新(化名)和其女友劉穎暴区,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體辛臊,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仙粱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浪讳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缰盏。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖淹遵,靈堂內(nèi)的尸體忽然破棺而出口猜,到底是詐尸還是另有隱情,我是刑警寧澤透揣,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布济炎,位于F島的核電站,受9級(jí)特大地震影響辐真,放射性物質(zhì)發(fā)生泄漏须尚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一侍咱、第九天 我趴在偏房一處隱蔽的房頂上張望耐床。 院中可真熱鬧,春花似錦楔脯、人聲如沸撩轰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)堪嫂。三九已至,卻和暖如春木柬,著一層夾襖步出監(jiān)牢的瞬間皆串,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工眉枕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恶复,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓速挑,卻偏偏與公主長(zhǎng)得像谤牡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子梗摇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容