xss防範小知識
一、背景
在Web安全中,xss攻擊絕對算是一種非常常見的攻擊方式了,它能夠竊取使用者的隱私資訊,比如cookie,也能夠做一些非使用者意圖的操作來達到攻擊目的。
二、原理
xss攻擊是一種非法指令碼的插入與執行攻擊,全稱為 cross site script ,即跨站指令碼攻擊。
通常我們訪問一個安全的網站時,瀏覽器會認為從該站點來的所有內容都是安全的,並按照html或者js等指令碼的內容去如實執行。但是當某個網站存在安全漏洞時,它便有可能被hacker利用起來,類似於SQL注入一般注入js指令碼,這時候,瀏覽器訪問該站點時,得到的內容便存在著安全隱患,執行的指令碼便會出現問題。
因此,本質上,xss攻擊就是一種js指令碼注入攻擊
三、分類
1、反射型攻擊
它是指瀏覽器在訪問某個地址時,通過引數的方式,在請求中添加了非法指令碼內容,服務端在接受到引數並處理完之後,將這些非法的使用者輸入響應到前端作為html一部分,前端最終執行了非法的指令碼。
2、儲存型攻擊
這種型別的攻擊,常見於存在使用者輸入的展示,比如說留言,評論,如果在這些內容中加入了非法指令碼,那麼瀏覽器在訪問這些內容時,便會執行非法指令碼。
3、DOM型攻擊
同樣,通過在url中構建非法的指令碼作為引數,前端直接獲取這些引數並進行展示時,便會不自覺地執行了非法的指令碼。
四、舉例子
1、前端直接取url中的引數,並拼接到頁面進行展示
<input type="text" value="<%= getParameter("keyword") %>"> <button>搜尋</button> <div> 您搜尋的關鍵詞是:<%= getParameter("keyword") %> </div>
假設我們訪問的頁面是:baidu.com?keyword=<script>alert('xss')</script>
那麼上述的頁面內容便成為了:
<input type="text" value="<%= getParameter("keyword") %>"> <button>搜尋</button> <div> 您搜尋的關鍵詞是:<script>alert('xss')</script> </div>
這時候,瀏覽器便會彈框‘xss’,也就不自覺地執行了我們注入的指令碼。
2、使用者點選觸發指令碼
通常,對於第一種例子,我們會想到對使用者的輸入進行特殊字元的轉義,然後再展示,但是這種方式並不能完全阻止指令碼的注入與執行.
例如對於a標籤,如果它的href地址為:
<a href="<%= escapeHTML(getParameter("redirect_to")) %>">跳轉...</a>
那麼當我們訪問的地址為:
baidu.com?redirect_to=javascript:alert('XSS')
哪怕進行了特殊字元的轉義,這時候html中的實際內容為:
<a href="javascript:alert('XSS')">跳轉...</a>
我們在點選該標籤時,還是會觸發指令碼。
因此,對於轉義,並不能夠完全的杜絕指令碼的注入,我們對於不同的場景,要對使用者的輸入內容進行不同程度的轉義操作。
五、防範
一個總的原則是需要對使用者的輸入進行過濾,認為使用者輸入的內容總是不可靠的。
1、對於後端
如果後端響應的資料需要拼接到html中,那麼我們需要對響應的資料進行轉義,通常是對 & < > / " ' 等幾個字元進行轉義。
2、對於前端
使用純前端渲染、將頁面程式碼和資料進行分離。
1、前段先載入靜態頁面
2、前端通過ajax獲取資料
3、通過DOM api將資料插入到頁面
在使用 .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,很容易產生安全隱患,請務必避免。
參考:
美團前端安全系列:https://tech.meituan.com/2018/09/27/fe-security.html