XSS(Cross-site scripting),指的是跨站脚本攻击,攻击者经过向页面A注入代码,达到窃取信息等目的,本质是数据被看成程序执行。XSS危害是很大的,通常XSS能够作到如下的事情:javascript
防护和“X-XSS-Protection”有关,默认值为1,即默认打开XSS防护,能够防护反射型的XSS,不过做用有限,只能防护注入到HTML的节点内容或属性的XSS,例如URL参数中包含script标签。不建议只依赖此防护手段。html
存在风险的代码:前端
<template>
<p>{{username}}</p>
</template>
<script>
username = "<script>alert('xss')</script>"
</script>
复制代码
编译后的代码:vue
<p>
<script>alert('xss')</script>
</p>
复制代码
以上例子是采用vue语法,但其实在vue这样的框架中,{{username}}中的内容是通过字符串化的,因此是不会被浏览器执行的,若换其余模板语言例如jade,则可能存在风险。下同。java
防护代码:git
经过转义<
为<
以及>
为>
来实现防护HTML节点内容。github
<template>
<p>{{username}}</p>
</template>
<script>
escape = function(str){
return str.replace(/</g, '<').replace(/>/g, '>')
}
username = escape("<script>alert('xss')</script>")
</script>
复制代码
<template>
<img :src="image" />
</template>
<script>
image = 'www.a.com/c.png" onload="alert(1)'
</script>
复制代码
编译后代码:数据库
<img src="www.a.com/c.png" onload="alert(1)" />
复制代码
防护代码:后端
经过转义"
为&quto;
、'
为'
来实现防护,通常不转义空格,可是这要求属性必须带引号!浏览器
<template>
<img :src="image" />
</template>
<script>
escape = function(str){
return str.replace(/"/g, '&quto;').replace(/'/g, ''').replace(/ /g, ' ') } image = escape('www.a.com/c.png" onload="alert(1)') </script> 复制代码
假设访问页面地址为www.a.com?id=1";alert(1);"
风险代码:
var id = getQuery('id')
复制代码
编译后代码:
var id = "1";alert(1);""
复制代码
防护代码:
经过将数据进行JSON序列化
escape = function(str){
return JSON.stringify(str)
}
复制代码
风险代码:
<template>
<p v-html="richTxt"></p>
</template>
<script>
richTxt = '<a onmouseover=alert(document.cookie)>点击</a>'
</script>
复制代码
上面的这段代码中,当鼠标移动到“点击”上面时,就会触发alert弹窗!这在vue中是会发生的。
防护富文本是比较复杂的工程,由于富文本能够包含HTML和script,这些难以预测与防护,建议是经过白名单的方式来过滤容许的HTML标签和标签的属性来进行防护,大概的实现方式是:
固然,也能够经过开源的第三方库来实现,相似的有js-xss。
CSP(content security policy),是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击等。
CSP能够经过HTTP头部(Content-Security-Policy)或<meta>
元素配置页面的内容安全策略,以控制浏览器能够为该页面获取哪些资源。好比一个能够上传文件和显示图片页面,应该容许图片来自任何地方,但限制表单的action属性只能够赋值为指定的端点。一个通过恰当设计的内容安全策略应该能够有效的保护页面免受跨站脚本攻击。
具体的配置描述能够移步MDN
vue已经在框架中进行了一些xss防护了,咱们对于一些外来的内容(例如接口或URL参数),尽可能用{{ }}表达式来显示,由于{{ }}中的内容通过字符串化,浏览器不会对其中的内容进行执行操做。
尽可能少用v-hmtl指令,或者先对内容进行xss过滤。虽然 HTML 5 中指定不执行由 innerHTML 插入的 "script" 标签。可是其中的标签是能够有执行javascript的监听函数的,例如onload、onerror、onmouseover等等。
CSRF(Cross Site Request Frogy)指的是跨站请求伪造。与XSS不一样的是,XSS是攻击者直接对咱们的网站A进行注入攻击,CSRF是经过网站B对咱们的网站A进行伪造请求。
举个例子,你登陆购物网站A以后点击一个恶意连接B,B请求了网站A的下单接口,结果是你在网站A的账号真的会生成一个订单。其背后的原理是:网站B经过表单、get请求来伪造网站A的请求,这时候请求会带上网站A的cookies,若登陆态是保存在cookies中,则实现了伪造攻击。
由于伪造GET请求的难度比POST请求的难度小(打开一个URL或是请求一个资源即是一个GET请求),因此对于涉及业务操做的接口,尽可能用POST请求,另外,CSRF的防护手段能够根据CSRF的特色来入手。
CSRF的一个特色是伪造请求不通过网站A
,那么咱们能够经过增长网站A的验证手段,例如增长图形验证码或短信验证码等等,只有经过验证的请求才算合法。可是这种方案拥有两个局限性,一个是增长开发成本,另一个是下降用户体验。
对于CSRF的第二个特色伪造请求的域名不是网站A
,那么经过限制cookies不被其余域名网站使用,来达到防护的目的,具体的作法是:
cookies设置sameSite属性的值为strict,这样只有同源网站的请求才会带上cookies。可是此方案有浏览器兼容问题。
第二个特色同时会形成伪造请求的referer不是网站A,所以咱们能够限制不信任的请求来源。具体作法是:
后端能够根据HTTP请求头的`referer`来判断请求是否来自可信任网站。可是这个方案也有局限性,攻击者能够设置请求不携带referer,因此这个方案适合用于辅助。
这是目前相对成熟的方案之一,具体的作法是:
服务端随机生成token,保存在服务端session中,同时保存到客户端中,客户端发送请求时,把token带到HTTP请求头或参数中,服务端接收到请求,验证请求中的token与session中的是否一致。
这个方案适用于先后端不分离的项目和先后端分离的项目,对于先后端不分离的项目,token能够直接在编译模板的过程当中写到表单的隐藏字段中,这样发送请求不须要额外的操做;而对于先后端分离的项目,token能够在登陆时写入到cookies中,发送请求时,js读取cookies中的token,并设置到HTTP请求头中。
由于CSRF本质是伪造请求携带了保存在cookies中的信息,因此对session机制的登陆态比较不利,若是更换JWT(JSON Web Token)方案,其token信息通常设置到HTTP头部的,因此能够防护CSRF攻击。
对于两种登陆态方案的优劣,这里就不展开了。
关于XSS和CSRF的东西就介绍到这里了,若是想了解除了XSS和CSRF以外的前端安全,能够点击本篇文章的小老弟: