# 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