1 輸入檢測(cè)
之前在 XSS 攻擊中有講過(guò)榨呆,攻擊者主要是通過(guò)構(gòu)造特殊字符來(lái)注入腳本屠橄,所以輸入檢測(cè)就很有必要兔魂。
輸入檢測(cè)烤芦,必須在服務(wù)端實(shí)現(xiàn)。因?yàn)槲鲂#粽呖梢岳@開(kāi) JavaScript 展開(kāi)攻擊构罗。業(yè)界的普遍做法是:同時(shí)在客戶端與服務(wù)端進(jìn)行輸入檢測(cè)≈遣#客戶的誤操作引起的問(wèn)題遂唧,可以通過(guò)客戶端 JavaScript 檢測(cè)出來(lái),從而節(jié)約服務(wù)器資源吊奢。而攻擊者的特殊字符入?yún)⒏桥恚蟛糠挚梢栽诜?wù)端被攔截下來(lái)。
輸入檢測(cè)中页滚,可以加入 XSS 特征檢測(cè)召边,這就是 XSS Filter。比如是否包含 <script>
標(biāo)簽等等裹驰。
但 XSS Filter 并不能真正理解語(yǔ)境隧熙、甚至可能出現(xiàn)改變客戶輸入語(yǔ)義的問(wèn)題。比如輸入公式:1+1 < 3幻林。 XSS Filter 會(huì)把敏感字符轉(zhuǎn)譯或者過(guò)濾掉贞盯,這就不是客戶希望看到的音念。
2 輸出檢測(cè)
2.1 非富文本輸出情境
非富文本輸出情境下,可以編碼或轉(zhuǎn)義可能造成 XSS 攻擊的特殊字符躏敢。
JavaScript 中可以使用 ESAPI 中的 DefaultEncoder#getInstance()#encodeForJavaScript()
來(lái)處理頁(yè)面輸出闷愤。
這里的 ESAPI 是 2.x。
除了 JavaScript 件余,這個(gè)類還針對(duì) CSS讥脐、HTML、SQL蛾扇、XML 等可能造成攻擊風(fēng)險(xiǎn)的點(diǎn)攘烛,也提供了相應(yīng)的編碼方法:
也可以使用 apache 的 org.apache.commons.text.StringEscapeUtils#escapeXxx()
方法。
lang3 中的 StringEscapeUtils镀首,已過(guò)時(shí)。
注意: 編碼后的數(shù)據(jù)鼠次,長(zhǎng)度可能發(fā)生變化更哄,而這有可能會(huì)對(duì)現(xiàn)有功能造成影響,開(kāi)發(fā)的時(shí)候需要注意腥寇。
XSS 的防御方法與輸出位置強(qiáng)相關(guān)成翩,我們要根據(jù)具體的輸出語(yǔ)境,選擇相應(yīng)的 ESAPI 方法對(duì)用戶的輸入變量進(jìn)行編碼赦役,說(shuō)明如下:
輸出位置 | ESAPI 對(duì)應(yīng)方法 |
---|---|
HTML 標(biāo)簽 | encodeForHTML |
script 標(biāo)簽和事件 | encodeForJavaScript |
CSS | encodeForCSS |
URL 地址 | encodeForURL |
2.2 富文本輸出情境
富文本一般來(lái)說(shuō)麻敌,是 HTML 代碼。我們首先可以通過(guò) HTML Parser 解析出 HTML 標(biāo)簽掂摔、屬性以及 JavaScript 事件术羔。因?yàn)楦晃谋局饕糜谡故荆詰?yīng)該嚴(yán)格禁止 JavaScript 事件乙漓。
富文本 HTML 標(biāo)簽與屬性的選擇级历,應(yīng)該采用白名單模式。比如只允許使用 <a>
叭披、<img>
寥殖、<div>
等相關(guān)安全的標(biāo)簽。
因?yàn)橛脩糇远x的 CSS 與 style 也可能導(dǎo)致 XSS 攻擊涩蜘,所以也需要禁止嚼贡。如果業(yè)務(wù)場(chǎng)景必須使用樣式,那我們可以使用 CSS Parser 對(duì)其進(jìn)行解析同诫,過(guò)濾掉其中所包含的危險(xiǎn)代碼粤策。