XSS(Cross-site scripting),指的是跨站腳本攻擊,攻擊者經過向頁面A注入代碼,達到竊取信息等目的,本質是數據被看成程序執行。XSS危害是很大的,通常XSS能夠作到如下的事情:javascript
防護和「X-XSS-Protection」有關,默認值爲1,即默認打開XSS防護,能夠防護反射型的XSS,不過做用有限,只能防護注入到HTML的節點內容或屬性的XSS,例如URL參數中包含script標籤。不建議只依賴此防護手段。html
存在風險的代碼:前端
<template>
<p>{{username}}</p>
</template>
<script>
username = "<script>alert('xss')</script>"
</script>
複製代碼
編譯後的代碼:vue
<p>
<script>alert('xss')</script>
</p>
複製代碼
以上例子是採用vue語法,但其實在vue這樣的框架中,{{username}}中的內容是通過字符串化的,因此是不會被瀏覽器執行的,若換其餘模板語言例如jade,則可能存在風險。下同。java
防護代碼:git
經過轉義<
爲<
以及>
爲>
來實現防護HTML節點內容。github
<template>
<p>{{username}}</p>
</template>
<script>
escape = function(str){
return str.replace(/</g, '<').replace(/>/g, '>')
}
username = escape("<script>alert('xss')</script>")
</script>
複製代碼
<template>
<img :src="image" />
</template>
<script>
image = 'www.a.com/c.png" onload="alert(1)'
</script>
複製代碼
編譯後代碼:數據庫
<img src="www.a.com/c.png" onload="alert(1)" />
複製代碼
防護代碼:後端
經過轉義"
爲&quto;
、'
爲'
來實現防護,通常不轉義空格,可是這要求屬性必須帶引號!瀏覽器
<template>
<img :src="image" />
</template>
<script>
escape = function(str){
return str.replace(/"/g, '&quto;').replace(/'/g, ''').replace(/ /g, ' ') } image = escape('www.a.com/c.png" onload="alert(1)') </script> 複製代碼
假設訪問頁面地址爲www.a.com?id=1";alert(1);"
風險代碼:
var id = getQuery('id')
複製代碼
編譯後代碼:
var id = "1";alert(1);""
複製代碼
防護代碼:
經過將數據進行JSON序列化
escape = function(str){
return JSON.stringify(str)
}
複製代碼
風險代碼:
<template>
<p v-html="richTxt"></p>
</template>
<script>
richTxt = '<a onmouseover=alert(document.cookie)>點擊</a>'
</script>
複製代碼
上面的這段代碼中,當鼠標移動到「點擊」上面時,就會觸發alert彈窗!這在vue中是會發生的。
防護富文本是比較複雜的工程,由於富文本能夠包含HTML和script,這些難以預測與防護,建議是經過白名單的方式來過濾容許的HTML標籤和標籤的屬性來進行防護,大概的實現方式是:
固然,也能夠經過開源的第三方庫來實現,相似的有js-xss。
CSP(content security policy),是一個額外的安全層,用於檢測並削弱某些特定類型的攻擊,包括跨站腳本 (XSS) 和數據注入攻擊等。
CSP能夠經過HTTP頭部(Content-Security-Policy)或<meta>
元素配置頁面的內容安全策略,以控制瀏覽器能夠爲該頁面獲取哪些資源。好比一個能夠上傳文件和顯示圖片頁面,應該容許圖片來自任何地方,但限制表單的action屬性只能夠賦值爲指定的端點。一個通過恰當設計的內容安全策略應該能夠有效的保護頁面免受跨站腳本攻擊。
具體的配置描述能夠移步MDN
vue已經在框架中進行了一些xss防護了,咱們對於一些外來的內容(例如接口或URL參數),儘可能用{{ }}表達式來顯示,由於{{ }}中的內容通過字符串化,瀏覽器不會對其中的內容進行執行操做。
儘可能少用v-hmtl指令,或者先對內容進行xss過濾。雖然 HTML 5 中指定不執行由 innerHTML 插入的 "script" 標籤。可是其中的標籤是能夠有執行javascript的監聽函數的,例如onload、onerror、onmouseover等等。
CSRF(Cross Site Request Frogy)指的是跨站請求僞造。與XSS不一樣的是,XSS是攻擊者直接對咱們的網站A進行注入攻擊,CSRF是經過網站B對咱們的網站A進行僞造請求。
舉個例子,你登陸購物網站A以後點擊一個惡意連接B,B請求了網站A的下單接口,結果是你在網站A的賬號真的會生成一個訂單。其背後的原理是:網站B經過表單、get請求來僞造網站A的請求,這時候請求會帶上網站A的cookies,若登陸態是保存在cookies中,則實現了僞造攻擊。
由於僞造GET請求的難度比POST請求的難度小(打開一個URL或是請求一個資源即是一個GET請求),因此對於涉及業務操做的接口,儘可能用POST請求,另外,CSRF的防護手段能夠根據CSRF的特色來入手。
CSRF的一個特色是僞造請求不通過網站A
,那麼咱們能夠經過增長網站A的驗證手段,例如增長圖形驗證碼或短信驗證碼等等,只有經過驗證的請求才算合法。可是這種方案擁有兩個侷限性,一個是增長開發成本,另一個是下降用戶體驗。
對於CSRF的第二個特色僞造請求的域名不是網站A
,那麼經過限制cookies不被其餘域名網站使用,來達到防護的目的,具體的作法是:
cookies設置sameSite屬性的值爲strict,這樣只有同源網站的請求才會帶上cookies。可是此方案有瀏覽器兼容問題。
第二個特色同時會形成僞造請求的referer不是網站A,所以咱們能夠限制不信任的請求來源。具體作法是:
後端能夠根據HTTP請求頭的`referer`來判斷請求是否來自可信任網站。可是這個方案也有侷限性,攻擊者能夠設置請求不攜帶referer,因此這個方案適合用於輔助。
這是目前相對成熟的方案之一,具體的作法是:
服務端隨機生成token,保存在服務端session中,同時保存到客戶端中,客戶端發送請求時,把token帶到HTTP請求頭或參數中,服務端接收到請求,驗證請求中的token與session中的是否一致。
這個方案適用於先後端不分離的項目和先後端分離的項目,對於先後端不分離的項目,token能夠直接在編譯模板的過程當中寫到表單的隱藏字段中,這樣發送請求不須要額外的操做;而對於先後端分離的項目,token能夠在登陸時寫入到cookies中,發送請求時,js讀取cookies中的token,並設置到HTTP請求頭中。
由於CSRF本質是僞造請求攜帶了保存在cookies中的信息,因此對session機制的登陸態比較不利,若是更換JWT(JSON Web Token)方案,其token信息通常設置到HTTP頭部的,因此能夠防護CSRF攻擊。
對於兩種登陸態方案的優劣,這裏就不展開了。
關於XSS和CSRF的東西就介紹到這裏了,若是想了解除了XSS和CSRF以外的前端安全,能夠點擊本篇文章的小老弟: