一. XSS
跨网站指令码(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程式的安全漏洞攻击,是代码注入的一种。它允许恶意使用者将程式码注入到网页上,其他使用者在观看网页时就会受到影响。这类攻击通常包含了 HTML 以及使用者端脚本语言。简称:跨站脚本攻击
XSS 分为三种:反射型,存储型和 DOM-based
如何攻击
XSS 通过修改 HTML 节点或者执行 JS 代码来攻击网站。
例如通过 URL 获取某些参数
<!-- Website Domain Names, Online Stores & Hosting - Domain.com<script>alert(1)</script> -->
<div>{
{name}}</div>
上述 URL 输入可能会将 HTML 改为 <div><script>alert(1)</script></div>
,这样页面中就凭空多了一段可执行脚本。这种攻击类型是反射型攻击,也可以说是 DOM-based 攻击。
也有另一种场景,比如写了一篇包含攻击代码 <script>alert(1)</script>
的文章,那么可能浏览文章的用户都会被攻击到。这种攻击类型是存储型攻击,也可以说是 DOM-based 攻击,并且这种攻击打击面更广。如何防御
最普遍的做法是转义输入输出的内容,对于引号,尖括号,斜杠进行转义
function escape(str) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '&quto;')
str = str.replace(/'/g, ''')
str = str.replace(/`/g, '`')
str = str.replace(/\//g, '/')
return str
}
通过转义可以将攻击代码 <script>alert(1)</script>
变成
// -> <script>alert(1)</script>
escape('<script>alert(1)</script>')
对于显示富文本来说,不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。这种情况通常采用白名单过滤的办法,当然也可以通过黑名单过滤,但是考虑到需要过滤的标签和标签属性实在太多,更加推荐使用白名单的方式。
var xss = require('xss')
var html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1><script>alert("xss");</script>
console.log(html)
以上示例使用了 js-xss
来实现。可以看到在输出中保留了 h1
标签且过滤了 script
标签
Vue 预防Xss攻击
1. 使用vue-xss 组件
2. 使用Xss 组件, 安装 xss 组件,添加xss验证,全局v-html 做xss过滤
a. 配置文件
新建一个xss.js文件, ,过滤掉样式和事件
const xss = require('xss')
const options = {
css: false,
onTag(tag, html, options) {
if (tag === 'iframe') {
return html.replace(/javascript:?/, '')
}
},
// 避免把页面样式过滤掉
onIgnoreTagAttr(tag, name, value, isWhiteAttr) {
// 过滤掉标签上的事件
if (/^[^on]/.test(name)) {
return name + '="' + xss.escapeAttrValue(value) + '"'
}
},
}
const filter = new xss.FilterXSS(options)
export default filter
b.挂载全局
main.js
//main.js
import xss from '@/utils/xss'
Vue.prototype.$xss = xss // 挂在全局是为了在 loader中能够通过该方法去过滤全局的 v-html 返回数据
c.模块化预处理,配置全局指令
在 vue.config.js 添加对 v-html 指令添加 xss 配置
// vue.config.js
// global xss rules
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap((options) => {
options.compilerOptions.directives = {
html(node, directiveMeta) {
const props = node.props || (node.props = [])
props.push({
name: 'innerHTML',
value: `$xss.process(_s(${directiveMeta.value}))`,
})
},
}
return options
})
二. CSRF
跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。[1] 跟跨網站指令碼(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
还是从字面上去分析,跨站还是指从一个网站指向另外一个网站,于XSS不同的是,他是请求,指我们在别的网站上发出一个请求,而这个请求是伪造出来的
⽤户已经登录了站点 A,并在本地记录了 cookie
在⽤户没有登出站点 A 的情况下(也就是 cookie ⽣效的情况下),访问了恶意攻击者提供的引诱危险站点 B (B 站点要求访问站点A)。
站点 A 没有做任何 CSRF 防御
攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
如何防御
防范 CSRF 可以遵循以下几种规则:
- Get 请求不对数据进行修改
- 不让第三方网站访问到用户 Cookie
- 阻止第三方网站请求接口
- 请求时附带验证信息,比如验证码或者 token
a.SameSite
可以对 Cookie 设置 SameSite
属性。该属性设置 Cookie 不随着跨域请求发送,该属性可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。
b.验证 Referer
对于需要防范 CSRF 的请求,我们可以通过验证 Referer 来判断该请求是否为第三方网站发起的。
c.Token(常用)
服务器下发一个随机 Token(算法不能复杂),每次发起请求时将 Token 携带上,服务器验证 Token 是否有效。