1. XSS攻击简介
XSS: 跨站脚本攻击,一个网站如果运行了非本站的脚本,那就可能产生XSS攻击。一旦发生了XSS,那攻击者就能够根据XSS漏洞来做很多事情。比如
- 获取页面数据
- 获取cookie
- 劫持前端逻辑
- 发送请求
这样可能带来诸多的危害,比如:
- 偷取网站的任意数据
- 偷取用户资料
- 偷取用户密码和登录态
- 欺骗用户
2. XSS分类
XSS攻击可以分为两大类
- 反射型:url参数直接注入
- 存储型:存储到DB后读取时注入
3.XSS攻击的注入点
- HTML节点内容
比如用户提交的文本中包含了一段script标签<script>alert(1)</script>
。如果这样这段脚本如果不经过任何转义直接插入到页面之后,就会产生XSS攻击。
- HTML属性
这个攻击通常用在img标签中。比如图片的url来自用户输入的内容
<img src="#{image}" alt="">
# 如果用户输入的内容为`1 onerror="<script>alert(1)</script>`
<img src="1 onerror="<script>alert(1)</script>" alt="">
这样就又导致了XSS攻击
- JavaScript代码
此类攻击通常是由于js代码中有一部分是来自于用户输入
<script >
const data = "#{content}";
// 比如用户输入的内容为 1"; alert(1);
const data = "1"; alert(1);
</script>
- 富文本
富文本里面是直接可以输入html标签的,这里如果不对用户输入的html标签进行过滤,就很可能产生XSS攻击。
4. 如何防御XSS攻击
- X-XSS-Protection
如果参数出现在HTML内容或属性中,可以设置响应头X-XSS-Protection: 1
,这个选项浏览器是默认打开的,它的用途也十分有限,如果它检测到有危害的输入直接被插入到html内容或者属性中,会直接屏蔽这个网页。
这个设定对JavaScript和富文本是无效的,也仅仅只能针对反射型的XSS。
- 防范HTML内容被XSS
将尖括号转义
function escape(str) {
return str.replace(/</g, '<')
.replace(/>/g, '>');
}
- 防范HTML属性被XSS
将引号转义(单引号和双引号),空格
function escape(str) {
return str.replace(/"/g, '&quto;')
.replace(/'/g, ''')
.replace(/s/g, ' ');
}
- 防范JS代码被XSS
将内容转化为JSON字符串
function escape(str) {
return JSON.stringify(str);
}
- 防范富文本被XSS
采用按白名单过滤的方式,比如Node中我们可以配合cheerio这个库来处理
function xssFilter(html) {
if (!html) return '';
const cheerio = require('cheerio');
const $ = cheerio.load(html);
const whileList = {
img: ['src'],
font: ['color', 'size'],
a: ['href']
};
$('*').each((index, ele) => {
if (!whileList[ele.name]) {
$(ele).remove();
return;
}
for (var attr in ele.attribs) {
if (whileList[ele.name].indexOf(attr) === -1) {
$(ele).attr(attr, null);
}
}
})
return $.html();
}
- CSP 内容安全策略
用来指定哪一部分可执行,哪一部分不可执行。比如我们可以在响应头中添加
ctx.set(`Content-Security-Policy`, `default-src 'self'`) // 仅信任同域脚本,内联脚本和其他域下的脚本将不会被执行
更多前端相关问题,请关注我的github: https://github.com/GuoLizhi/awesomejs/