XSS 跨站脚本攻击
程序+数据 = 结构,在动态输入数据的位置加入一段脚本
- 获取页面数据,偷取网站任意数据
- 获取 cookies,偷取用户资料
- 劫持前端逻辑,偷取用户密码和登录状态
- 发起请求,欺骗用户
类型
- 反射性:url 参数直接注入
- 存储型:存储到 数据库 后读取时注入,比如在在留言板进行存入一个脚本
XSS 攻击注入点
- HTML 节点内容,html 节点内混入 script 脚本
- HTML 属性
<img src="1" onerror="alert(1)">,超过属性本身,产生一个新属性 - js 代码,由后台注入的变量,用户输入的信息改变代码逻辑 text 文本中插入一段代码
- 富文本,html 和 js 代码混入形式,html+文字
HTML 节点内容攻击 如何防御
- header 头 ctx.set('X-XSS-Protection',1),出现在 html 内容,html 属性,防止反射性的攻击
- 在数据库前转义,在显示之前
var escapehtml = function(str) {
if (!str) {
return '';
}
str = str.replace(/&/g, '&');
str = str.replace(/</g, '<');
str = str.replace(/>/g, '>');
str = str.replace(/"/g, '&quto;');
str = str.replace(/'/g, ''');
return str;
};
HTML 属性攻击 如何防御
var escapejs = function() {
if (!str) {
return '';
}
str = str.replace(/\\/g, '\\\\');
str = str.replace(/"/g, '\\"');
return str;
};
富文本攻击如何防御
- 使用 cheerio 去过滤
// var cheerio = require("cheerio);
var cheerioFilter = function(html) {
var $ = cheerio.load(html);
// 白名单
var whiteList = {
img: ['src'],
font: ['color', 'size'],
a: ['href']
};
$('*').each((index, elem) => {
if (!whiteList[elem.name]) {
$(elem).remove();
return;
}
for (var attr in elem.attribs) {
if (whiteList[elem.name].indexOf(attr) == -1) {
$(elem).attr(attr, null);
}
}
});
return $.html();
};
- 使用 xss 库 去过滤
// var xss = require("xss");
var xssFilter = function(html) {
// options = {}; // 自定义规则
// html = xss('<script>alert("xss");</script>', options);
// 自定义匹配到不在白名单上的标签时的处理方法
var ret = xss(html, {
// 白名单,不在白名单上的标签将被过滤,不在白名单上的属性也会被过滤
whiteList: {
a: ['href', 'title', 'target'],
span: ['style']
},
onIgnoreTag: (tag, html, options) => {
return '';
}
});
console.log(ret);
return ret;
};
xssFilter('<a href="javascript:alert(123)" title="hello">');
xssFilter('<script href="www.baidu.com">123</script>');
xssFilter('<span style="color:red">123</span>');
CSP 内容安全策略
主要目的是减少和报告 XSS 攻击
// 一个网站管理者想要所有内容均来自站点的同一个源 (不包括其子域名)
ctx.set(`Content-Security-Policy`, `default-src 'self'`);
确认评论邮箱
邀请制评论