# xss攻擊
cross site scripting(跨站腳本攻擊)
# 風險
* 獲取頁面數據
* 獲取cookie
* 劫持前端邏輯
* 發送請求
* 偷取網站任意數據
* 偷取用戶資料
* 偷取用戶密碼和登陸態
* 欺騙用戶
# 攻擊的類型
* 反射型:通過url參數注入
* 存儲型:存儲到DB后讀取時注入
# XSS攻擊注入點
* HTML節點內容
```html
<div>#{content}</div>
// 有可能被解析成
<div><script>alert(1)</script></div>
```
* HTML屬性
```html
<img src="#{image}" />
// 有可能被解析成
<img src="1" onerror="alert(1)" />
```
* Javascript 代碼
```javascript
var data = "#{data}";
// 有可能被解析成
var data = "hello";alert(1);"";
```
* 富文本
> 富文本得保留HTML
> HTML有XSS攻擊風險
# 防御
* 瀏覽器自帶的防御:反射型攻擊(url中的參數出現在 `HTML節點` 或 `HTML屬性` 中時)
> 可通過設置 `X-XSS-Protection` 返回頭來關閉這個防御(默認是打開的),但不是所有瀏覽器都支持
* HTML節點內容
> 轉義 `<` 和 `>`
```javascript
function escapeHtml (str) {
if (!str) return ''
return str.replace(/</g, '<').replace(/>/g, '>')
}
```
* HTML屬性
> 轉義 `"` `'` 和 空格
```javascript
function escapeHtmlProperty (str) {
if (!str) return ''
return str.replace(/"/g, '&quto;').replace(/'/g, ''').replace(/ /g, ' ')
}
```
* javascript 代碼
> 轉義 `"` 或者轉換成 JSON
```javascript
function escapeJS (str) {
if (!str) return ''
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"')
}
// 或者
JSON.stringify(str)
```
* 富文本
> 按黑名單過濾
```javascript
function xssFilter (str) {
if (!str) return ''
return str.replace(/<\s*\/?script\s*>/g, ' ').replace(/javascript:[^'"]*/g, '').replace(/onerrror\s*=\s*['"]?[^'"]*['"]?/g, '') //...
}
```
> 按白名單保留部分標簽和屬性
```
// npm install cheerio -S
// javascript
var whiteList = {
'img': ['src']
}
function xssFilter (html) {
if (!str) return ''
var cheerio = require('cheerio')
var $ = cheerio(html)
$('*').each(function(index, ele) {
if (!whiteList[ele.name]) {
$(ele).remove()
return
}
for (var attr in ele.attribs) {
if (whiteList[ele.name].indexOf(attr) === -1) {
$(ele).attr(attr, null)
}
}
}
return $.html()
}
```
```
或者使用 xss 庫
npm install xss
function xssFilter (html) {
if (!str) return ''
var xss = require('xss')
return xss(html)
}
```
# CSP
content security Policy(內容安全策略),用于指定哪些內容可執行,在返回頭中設置
# PHP中防御XSS
* 內置函數轉義
```
$content = strip_tags($content) // 移除html標簽,只保留html內容
$content = htmlspecialchars($content, ENT_QUOTES) // 對指定的字符做轉義, & < > ' "
```
* DOM解析白名單
* 第三方庫
> HTML Purifier(htmlpurifier.org)
* CSP