【缺陷周話】第12期:儲存型 XSS
1、儲存型 XSS
儲存型XSS 是指應用程式通過Web請求獲取不可信賴的資料,在未檢驗資料是否存在XSS程式碼的情況下,便將其存入資料庫。當下一次從資料庫中獲取該資料時程式也未對其進行過濾,頁面再次執行XSS程式碼,儲存型XSS可以持續攻擊使用者。儲存型XSS漏洞大多出現在留言板、評論區,使用者提交了包含XSS程式碼的留言到資料庫。當目標使用者查詢留言時,那些留言的內容會從伺服器解析之後加載出來。瀏覽器發現有XSS程式碼,就當做正常的HTML和JS解析執行,儲存型XSS就發生了。本篇文章以JAVA語言原始碼為例,分析CWE ID 80:ImproperNeutralization of Script-Related HTML Tags in a Web Page (Basic XSS)(http://cwe.mitre.org/data/definitions/80.html)樣本儲存型XSS漏洞產生的原因以及修復方法。 詳見:
- CWE ID 79: ImproperNeutralization of Input During Web Page Generation (‘Cross-site Scripting’) (http://cwe.mitre.org/data/definitions/79.html)
- CWE ID 80: Improper Neutralization ofScript-Related HTML Tags in a Web Page (Basic XSS)(http://cwe.mitre.org/data/definitions/80.html)
- CWE ID 81: Improper Neutralization of Scriptin an Error Message Web Page (http://cwe.mitre.org/data/definitions/81.html)
- CWE ID 82: Improper Neutralization of Scriptin Attributes of IMG Tags in a Web Page (http://cwe.mitre.org/data/definitions/82.html)
- CWE ID 83: Improper Neutralization of Scriptin Attributes in a Web Page (http://cwe.mitre.org/data/definitions/83.html)
2、 儲存型 XSS 的危害
儲存型XSS攻擊方式主要是嵌入一段遠端或者第三方域上的JS程式碼,並在目標域執行這些程式碼。儲存型XSS會造成Cookie洩露,破壞頁面正常的結構與樣式,重定向訪問惡意網站等。從2018年1月至11月,CVE中共有215條漏洞資訊與其相關。部分漏洞如下:
CVE | 漏洞概述 |
---|---|
CVE-2018-19178 | 在JEESNS 1.3中,com / lxinet / jeesns / core / utils /XssHttpServletRequestWrapper.java允許通過 HTML EMBED 元素進行儲存型XSS攻擊。 |
CVE-2018-19170 | JPress,一個 wordpress 的 java 代替版本,使用 JFinal 開發,支援類似 wordpress 的幾乎所有功能。在 JPress v1.0-rc.5 中,通過前面三個輸入欄位,可進行儲存型XSS攻擊 starter-tomcat-1.0 / admin / setting URI。 |
CVE-2018-19089 | Tianti是基於 Java 的輕量級 CMS 解決方案,tianti 2.3 通過 tianti-module-admin / user /ajax / save_role name 引數在使用者列表模組存在儲存型XSS漏洞,該引數在 tianti-module-admin src main webapp WEB-INF views user user_list.jsp。 |
CVE-2018-17369 | Java EasyCms 是一個開源 cms 系統。發表文章時, EasyCMS 1.3 存在儲存型XSS漏洞; 四個欄位受到影響:標題,關鍵字,摘要和內容,如 /admin/index/index.html#listarticleURI所示。 |
3、示例程式碼
示例源於 SamateJuliet Test Suite for Java v1.3 (https://samate.nist.gov/SARD/testsuite.php),原始檔名:CWE80_XSS__CWE182_Servlet_database_01.java。
3.1缺陷程式碼
上述示例程式碼操作是獲取使用者姓名輸出到頁面。在第46行獲取資料庫連線物件,第49行建立查詢語句查詢id等於0的使用者姓名,在第55行將結果集賦值給 data。在第108行僅過濾了 <script> 標籤並輸出給頁面。事實上來自於資料庫的資料被認為是不安全的,程式與使用者互動時產生危險資料未經驗證或繞過安全驗證存入資料庫,再從資料庫中獲取資料時,這些危險資料有可能導致資訊洩露,頁面劫持等安全威脅。當查詢的使用者名稱為 alert(“document.cookie”) 時,僅僅過濾 <script> 標籤不足以解決其他 html 標籤,向頁面輸出查詢結果時會洩露使用者 Cookie。
使用360程式碼衛士對上述示例程式碼進行檢測,可以檢出“儲存型XSS”缺陷,顯示等級為高。從跟蹤路徑中可以分析出資料的汙染源以及資料流向,在程式碼行第108行報出缺陷,如圖1所示:
圖1:儲存型 XSS 檢測示例
3.2 修復程式碼
在上述修復程式碼中,第56行使用 ESAPI(ESAPI 是 OWASP 提供的一套 API 級別的開源 WEB 應用解決方案,可以幫助開發者編寫更加安全的程式碼)中的 encodeForHTML() 方法對查詢到的使用者名稱進行 HTML 編碼,當出現敏感字元時,將使用替代字元編碼敏感字元。
使用360程式碼衛士對修復後的程式碼進行檢測,可以看到已不存在“儲存型XSS”缺陷。如圖2:
圖2:修復後檢測結果
4 、如何避免儲存型 XSS
要避免儲存型 XSS,需要注意以下幾點:
(1)對使用者的輸入進行合理驗證,對特殊字元(如<、>、’、”等)以及 <script>、 javascript 等進行過濾。
(2)採用 OWASP ESAPI 對資料輸出 HTML 上下文中不同位置(HTML 標籤、HTML 屬性、JavaScript 指令碼、CSS、URL)進行恰當的輸出編碼。
(3)設定 HttpOnly 屬性,避免攻擊者利用跨站指令碼漏洞進行 Cookie 劫持攻擊。在 Java EE 中,給 Cookie 新增 HttpOnly 的程式碼如下: