邏輯漏洞挖掘之XSS漏洞原理分析及實戰演練 | 京東物流技術團隊

發表於2023-09-27

一、前言

2月份的1.2億條使用者地址資訊洩露再次給各大公司敲響了警鐘,資料安全的重要性愈加凸顯,這也更加堅定了我們推行安全測試常態化的決心。隨著測試組安全測試常態化的推進,有更多的同事對邏輯漏洞產生了興趣,本系列文章旨在揭秘邏輯漏洞的範圍、原理及預防措施,逐步提升大家的安全意識。作為開篇第一章,本文選取了廣為熟知的XSS邏輯漏洞進行介紹。

二、XSS漏洞介紹

1.XSS漏洞的定義

跨站指令碼(Cross Site Script),為了不和層疊樣式表(Cascading Style Sheets,CSS)的縮寫混淆,故將跨站指令碼縮寫為XSS。跨站指令碼(以下簡稱XSS)通常發生在客戶端,攻擊者在Web頁面中插入惡意JavaScript程式碼(也包括VBScript和ActionScript程式碼等),使用者瀏覽此頁面時,會執行這些惡意程式碼,從而使使用者受到攻擊。

2.XSS主要攻擊形式

  • 儲存型跨站指令碼攻擊

攻擊者利用應用程式提供的新增、修改資料功能,將惡意資料儲存到伺服器中,當其他使用者瀏覽展示該資料的頁面時,瀏覽器會執行頁面嵌入的惡意指令碼,從而達到惡意攻擊的目的,這種攻擊是持久化的。

  • 反射型跨站指令碼攻擊

攻擊者傳送一個URL給使用者並誘導其訪問,瀏覽器會執行頁面嵌入的惡意指令碼,從而達到惡意攻擊的目的,這種攻擊只執行一次,是非持久化的。

  • DOM跨站指令碼攻擊

在Html頁面中,未透過規範JavaScript直接操作使用者輸入的資料,當攻擊者插入一段惡意程式碼,在頁面最終展示會執行惡意指令碼,從而達到惡意攻擊的目的。

3.XSS漏洞危害

  • 資訊竊取(如盜取使用者cookie,偽造使用者身份登入)
  • 釣魚欺詐
  • 蠕蟲攻擊

三、XSS漏洞原理分析

四、XSS漏洞例項分析

1.儲存型XSS

  • 漏洞位置其實為兩處,此處類似iframe嵌⼊,原url為test.jd.com,所以直接影響兩個站

  • 漏洞證明:傳送如下資料包,即可插⼊儲存型XSS

2.反射型XSS

  • 輸入萬能語句 <script>alert()</script>後並沒有彈窗,檢視原始碼可見 <>被轉義了

  • 在input標籤的value處,沒有將我們輸入的內容進行嚴格過濾,所以手動閉合value,再執行指令碼 "><script>alert()</script>

五、XSS漏洞防範意見

1.儲存型和反射型 XSS

儲存型和反射型 XSS 都是在服務端取出惡意程式碼後,插入到響應 HTML 裡的,攻擊者刻意編寫的“資料”被內嵌到“程式碼”中,被瀏覽器所執行。預防這兩種漏洞,有兩種常見做法:

1)改成純前端渲染,把程式碼和資料分隔開

對 HTML 做充分轉義。瀏覽器先載入一個靜態 HTML,此HTML 中不包含任何跟業務相關的資料。然後瀏覽器執行 HTML 中的 JavaScript。JavaScript 透過 Ajax 載入業務資料,呼叫 DOM API 更新到頁面上。在純前端渲染中,我們會明確的告訴瀏覽器:下面要設定的內容是文字(.innerText),還是屬性(.setAttribute),還是樣式(.style)等等。瀏覽器不會被輕易的被欺騙,執行預期外的程式碼了。

但純前端渲染還需注意避免 DOM 型 XSS 漏洞(例如 onload 事件和 href 中的 javascript:xxx 等,請參考下文”預防 DOM 型 XSS 攻擊“部分)。在很多內部、管理系統中,採用純前端渲染是非常合適的。但對於效能要求高,或有 SEO 需求的頁面,我們仍然要面對拼接 HTML 的問題。

2)轉義 HTML

如果拼接 HTML 是必要的,就需要採用合適的轉義庫,對 HTML 模板各處插入點進行充分的轉義。

常用的模板引擎,如 doT.js、ejs、FreeMarker 等,對於 HTML 轉義通常只有一個規則,就是把 & < >

" ’ / 這幾個字元轉義掉.

2.預防 DOM 型 XSS 攻擊

DOM 型 XSS 攻擊,實際上就是網站前端 JavaScript 程式碼本身不夠嚴謹,把不可信的資料當作程式碼執行了。

在使用 .innerHTML、.outerHTML、document.write() 時要特別小心,不要把不可信的資料作為 HTML 插到頁面上,而應儘量使用 .textContent、.setAttribute() 等。

如果用 Vue/React 技術棧,並且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 階段避免 innerHTML、outerHTML 的 XSS 隱患。

DOM 中的內聯事件監聽器,如 location、onclick、onerror、onload、onmouseover 等,a 標籤的 href 屬性,JavaScript 的 eval()、setTimeout()、setInterval() 等,都能把字串作為程式碼執行。如果不可信的資料拼接到字串中傳遞給這些 API,很容易產生安全隱患,請務必避免。

3.其他 XSS 防範措施

雖然在渲染頁面和執行 JavaScript 時,透過謹慎的轉義可以防止 XSS 的發生,但完全依靠開發的謹慎仍然是不夠的。以下介紹一些通用的方案,可以降低 XSS 帶來的風險和後果。

1)Content Security Policy

嚴格的 CSP 在 XSS 的防範中可以起到以下的作用:

禁止載入外域程式碼,防止複雜的攻擊邏輯。

禁止外域提交,網站被攻擊後,使用者的資料不會洩露到外域。

禁止內聯指令碼執行(規則較嚴格,目前發現 GitHub 使用)。

禁止未授權的指令碼執行(新特性,Google Map 移動版在使用)。

合理使用上報可以及時發現 XSS,利於儘快修復問題。

關於 CSP 的詳情,請關注前端安全系列後續的文章。

2)輸入內容長度控制

對於不受信任的輸入,都應該限定一個合理的長度。雖然無法完全防止 XSS 發生,但可以增加 XSS 攻擊的難度。

3)其他安全措施

HTTP-only Cookie: 禁止 JavaScript 讀取某些敏感 Cookie,攻擊者完成 XSS 注入後也無法竊取此Cookie。

作者:京東物流 範文君
來源:京東雲開發者社群 自猿其說 Tech 轉載請註明來源