XSS 是跨站腳本攻擊(Cross Site Scripting)的簡寫,可是從首寫字母命名的方式來看,應該取名 CSS,但這樣就和層疊樣式表(Cascading Style Sheets,CSS)重名了,因此取名爲 XSS。html
XSS 攻擊,通常是指攻擊者經過在網頁中注入惡意腳本,當用戶瀏覽網頁時,惡意腳本執行,控制用戶瀏覽器行爲的一種攻擊方式。前端
XSS 攻擊按是否把攻擊數據存進服務器端,攻擊行爲是否伴隨着攻擊數據一直存在,可分爲 非持久型 XSS 攻擊 和 持久型 XSS 攻擊。git
XSS 攻擊按攻擊方式又可分爲 反射型 XSS、DOM 型 XSS、存儲型 XSS,其中 反射型 XSS 和 DOM 型 XSS 算是 非持久型 XSS 攻擊,而 存儲型 XSS 算是 持久型 XSS 攻擊。github
攻擊者誘導用戶訪問一個帶有惡意代碼的 URL 後,服務器端接收數據後處理,而後把帶有惡意代碼的數據發送到瀏覽器端,瀏覽器端解析這段帶有 XSS 代碼的數據後當作腳本執行,最終完成 XSS 攻擊。
由於這個過程就像一次反射,故稱爲反射型 XSS。後端
攻擊步驟:
一、攻擊構造出特殊的 URL ,其中包含惡意代碼。
二、用戶被誘導打開帶有惡意代碼的 URL,服務器端將惡意代碼從 URL 中取出當作參數處理,而後返回給用戶帶有惡意代碼的數據。
三、用戶瀏覽器接收到響應解析執行,混在其中的惡意代碼也被執行。
四、惡意代碼竊取用戶敏感數據發送給攻擊者,或者冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操做。 瀏覽器
下面是一個正常的搜索流程安全
一、打開首頁,輸入搜索內容 服務器
https://www.kkkk1000.com/xss/Reflected/index.html
cookie
二、開始搜索,查看結果 併發
https://www.kkkk1000.com/xss/Reflected/searchResult.html?kw=斗羅大陸
可是若是沒有搜索到結果,後端也會返回用戶輸入的內容,而後顯示在頁面上。
https://www.kkkk1000.com/xss/Reflected/searchResult.html?kw=xxx
由於這裏沒有對用戶輸入的數據作處理,因此咱們構造這樣一個連接:
https://www.kkkk1000.com/xss/Reflected/searchResult.html?kw=<script>alert("xss")</script>
而後誘導他人點擊這個連接,就能夠完成一次反射型 XSS 攻擊。
而對於這麼長的連接,咱們還能夠假裝假裝,轉爲短網址或者二維碼。
短網址:
二維碼:
也許你以爲只是一個彈框而已,問題不大,但若是咱們把攻擊代碼變爲加載一個第三方的 js 文件呢?變爲用 document.cookie
盜取 cookie 的代碼呢?總之若是是真的攻擊的話,就不會只是一個彈框這麼簡單了。
DOM 型 XSS 造成緣由是經過修改頁面的 DOM 節點造成的 XSS。
DOM 型 XSS 攻擊中,取出和執行惡意代碼都由瀏覽器端完成,屬於前端自身的安全漏洞。
攻擊步驟:
一、攻擊者構造出特殊的 URL,其中包含惡意代碼。
二、用戶被誘導打開帶有惡意代碼的 URL。
三、用戶瀏覽器接收到響應後解析執行,前端 JavaScript 取出 URL 中的惡意代碼並執行。
四、惡意代碼竊取用戶數據併發送到攻擊者的網站,或者冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操做。
下面是一個物流詳情的頁面,在 URL 上有快遞編號這個參數,經過這個參數來獲取數據。
https://www.kkkk1000.com/xss/dom/index.html?serialNumber=YT40359134268305
由於在源碼中能夠看到,頁面上顯示的快遞編號,是直接取的 URL 上的參數顯示的。因此咱們構造這樣一個網址:
https://www.kkkk1000.com/xss/dom/index.html?serialNumber=<script>alert("xss")</script>
而後誘導他人點擊這個連接,就能夠完成一次 DOM 型 XSS 攻擊。
存儲型 XSS 跟 反射型 XSS 的區別是:存儲型 XSS 的惡意代碼存在服務器上,反射型 XSS 的惡意代碼存在 URL 裏。
存儲型 XSS 攻擊時惡意腳本會存儲在目標服務器上。當瀏覽器請求數據時,腳本從服務器傳回並執行。它是最危險的一種跨站腳本,比反射性 XSS 和 DOM 型 XSS 都更有隱蔽性,由於它不須要用戶手動觸發。任何容許用戶存儲數據的 Web 程序均可能存在存儲型 XSS 漏洞。若某個頁面遭受存儲型 XSS 攻擊,全部訪問該頁面的用戶都會被 XSS 攻擊。
攻擊步驟:
一、攻擊者把惡意代碼提交到目標網站的服務器中。
二、用戶打開目標網站,網站服務器端把帶有惡意代碼的數據取出,當作正常數據返回給用戶。
三、用戶瀏覽器接收到響應解析執行,混在其中的惡意代碼也被執行。
四、惡意代碼竊取用戶敏感數據發送給攻擊者,或者冒充用戶的行爲,調用目標網站接口執行攻擊者指定的操做。
這是一個能夠評論的文章的頁面
https://www.kkkk1000.com/xss/Stored/index.html
可是,評論的內容是沒有處理過的,因此咱們若是輸入這樣的內容: <script>alert("xss")</script>
一樣是能夠做爲評論的。
咱們用這樣的內容做爲評論後,全部打開這篇文章的用戶都會遭到存儲型 XSS 攻擊。
HTTP X-XSS-Protection 響應頭是 Internet Explorer,Chrome 和 Safari 的一個功能,當檢測到跨站腳本攻擊(XSS)時,瀏覽器將中止加載頁面。
他能夠設置4個值:
X-XSS-Protection: 0 禁止XSS過濾。 X-XSS-Protection: 1 啓用XSS過濾(一般瀏覽器是默認的)。 若是檢測到跨站腳本攻擊,瀏覽器將清除頁面(刪除不安全的部分)。 X-XSS-Protection: 1; mode=block 啓用XSS過濾。 若是檢測到攻擊,瀏覽器將不會清除頁面,而是阻止頁面加載。 X-XSS-Protection: 1; report=<reporting-uri> 啓用XSS過濾。 若是檢測到跨站腳本攻擊,瀏覽器將清除頁面並使用CSP report-uri指令的功能發送違規報告。
這種瀏覽器自帶的防護功能只對反射型 XSS 有必定的防護力,其原理是檢查 URL 和 DOM 中元素的相關性,但這並不能徹底防止反射型 XSS,並且也並非全部瀏覽器都支持 X-XSS-Protection。
在 XSS 攻擊中,攻擊者主要是經過構造特殊字符來注入腳本,因此對用戶的輸入進行檢測就頗有必要,而且須要在客戶端與服務端都進行輸入檢測,而後對用戶輸入的數據進行轉義。
主要就是對輸入所包含的特殊字符進行轉義,如 <
,>
,&
,"
,'
,來防止 XSS 攻擊。
下面是一個用於轉義的方法:
function escapeHTML(str) { if (!str) return ''; str = str.replace(/&/g, "&"); str = str..replace(/</g, "<"); str = str..replace(/>/g, ">"); str = str..replace(/"/g, """); str = str..replace(/'/g, "'"); return str; };
在富文本中由於須要保留 HTML ,因此咱們不能使用轉義的方法防護 XSS 攻擊,這裏使用過濾的方式防護 XSS 攻擊,也就是經過只使用白名單容許的 HTML 標記及其屬性,來防護攻擊。
這裏推薦一個名爲 XSS 的組件 ,這就是一個根據白名單過濾 HTML,防止 XSS 攻擊的組件。
內容安全策略(Content Security Policy,CSP),實質就是白名單制度,開發者明確告訴客戶端,哪些外部資源能夠加載和執行,大大加強了網頁的安全性。
兩種方法能夠啓用 CSP。一種是經過 HTTP 頭信息的 Content-Security-Policy 的字段。
Content-Security-Policy: script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:
另外一種是經過網頁的 <meta>
標籤。
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
上面代碼中,CSP 作了以下配置。
<object>
標籤: 不信任任何 URL,即不加載任何資源<frame>
、<iframe>
: 必須使用HTTPS協議加載啓用後,不符合 CSP 的外部資源就會被阻止加載。
XSS 攻擊的本質就是輸入的內容被當作程序執行了,因此咱們對於用戶輸入的內容不能徹底的信任,須要考慮如何避免其被當作程序執行。
這裏舉幾個真實的 XSS 攻擊案例,你們瞭解下。
前端安全系列(一):如何防止XSS攻擊?
Web先後端漏洞分析與防護
XSS那些事兒
Content Security Policy 入門教程
CSP 策略指令