阅读 120

前端安全防范

最近组内统一接入了CSP&CSRF相关的解决方案,趁着这次机会本酱重新回顾了一下前端安全相关的知识点,话不多说我们来一起巩固一下这些内容。

XSS

XSS(Cross Site Scripting),跨站脚本攻击之所以缩写为XSS主要是为了与层叠样式表(Cascading Style Sheets)做区分。这种类型的攻击主要是通过将恶意代码注入到网页中使用户加载并执行恶意代码。

种类

  1. 持久型: 危害系数高的一种攻击类型,因为攻击者已经将恶意代码通过页面注入到了数据库中(所以也称作存储型攻击),是一种持久性的伤害,用户每次打开页面时就会执行相关的代码,通常出现在网站的评论、留言,博客日志等处。
  2. 非持久型: 相比持久型的危害系数要低,主要是攻击者在URL上携带攻击代码当用户访问特定的链接时如果我们对参数不加过滤就会导致攻击代码被执行,例如以下这种:
url: http://www.jianglihua.com?name=<script>alert('jiang jiang jiang')</script>
html: <div>{name}</div>
复制代码

当用户访问这个网址的时候就会弹出来带有 'jiang jiang jiang'的警告框,如果是携带了其他的攻击性代码的话可能会给用户带来比较大的损失,比如窃取用户cookie盗取用户隐私等。有人会说这种链接一看就有问题呀用户肯定不会去点击的,但是对于这种长链接攻击者可以通过工具转换成用户难以识别的短链接再诱导用户进行点击,或者转成一个二维码让用户扫码以达到攻击的目的。

防御办法

  1. 转义
    本着对用户的输入永不信任的原则,最普遍的做法便是对用户的输入输出的内容进行转义,以下是一个常见的转义方法:
function escape(str) {
    str = str.replace(/&/g, '&amp;')
    str = str.replace(/</g, '&lt;')
    str = str.replace(/>/g, '&gt;')
    str = str.replace(/"/g, '&quto;')
    str = str.replace(/'/g, '&#39;')
    str = str.replace(/`/g, '&#96;')
    str = str.replace(/\//g, '&#x2F;')
    return str
}
复制代码

举个例子:

<script>alert('jiang jiang jiang')</script> // 转义前
&lt;script&gt;alert(&#39;jiang jiang jiang&#39;)&lt;&#x2F;script&gt;  // 转义后
复制代码

对于特殊的场景比如富文本,如果同样也采用这种方式的话显然是不行的,因为富文本本身就需要保留HTML,对于这种情况我们可以使用一个XSS包然后通过增加白名单的方式来过滤相关的HTML。

  1. 开启CSP(Content-Security-Policy)
    内容安全策略的本质还是白名单机制,开发人员通过设置一系列的配置来告诉浏览器哪些外部资源是可以加载和运行的,这样即使攻击者注入了恶意代码也无法被执行。开启CSP有两种方法:

    • 设置HTTP Header头中的:"Content-Security-Policy"
    • 设置meta标签:<meta http-equiv="Content-Security-Policy">

    开启了CSP后可以做哪些配置呢,我们来看几个指令:

    指令名 指令说明
    default-src 默认值,如果以下几个指令都没有设置的话会执行当前指令的配置;如果当前指令和下面的指令之一同时存在则下面的指令会覆盖当前指令,比如设置了 default-src 'none'; script-src 'self';则对于js资源来说会执行script-src 'self'
    script-src 定义外部脚本的过滤策略
    img-src 定义外部图片的过滤策略
    style-src 定义外部样式的过滤策略
    object-src 定义页面插件的过滤策略
    ... ...

    所有以 -src 结尾的指令都支持以下类似的值用于定义过滤规则:

    指令值 示例 说明
    * img-src * 通配符,允许任意来源的URL,但不包括: blob: filesystem: schemes
    'none' object-src 'none' 所有的资源都禁止加载
    'self' script-src 'self' 遵循同源策略,只允许符合同源策略的资源加载
    data: img-src 'self' data: 允许通过data请求来获取资源,比如用Base64编码过的图片
    domain.example.com img-src domain.example.com 允许指定的域名下的资源加载
    https: img-src https: 只允许通过https协议加载资源
    ... ... ...

    除此之外还可以 查看更多 配置策略,这里就不再一一赘述。目前主流的浏览器大都已经支持CSP特性:

CSRF

CSRF(Cross-site request forgery)跨站请求伪造是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。与XSS相比,XSS利用的是用户对指定网站的信任,而CSRF利用的是网站对用户浏览器的信任。

攻击流程

从以上流程中我们可以发现攻击一般发生在第三方网站且攻击者并不是直接盗取用户的相关信息而是冒用用户的身份进行非法请求,根据这些特性我们可以得到一些常用到的防范措施。

防范措施

  1. 携带Token:
    服务端下发一个随机Token,用户每次请求接口时将Token带上,服务端验证Token是否有效
  2. 设置SameSite:
    SameSite Cookie 允许服务器要求某个cookie在跨站请求时不会被发送,
    eg: Set-Cookie: [key]=[value]; SameSite=strict,SameSite有三个可以设置的值:
    • None: 相当于没有设置,浏览器会在所有请求中(包括同站和跨站请求)包含cookie
    • Strict: 浏览器只有在访问相同站点时才会携带cookie
    • Lax: 宽松模式,相比Strict模式而言,Lax模式允许用户从外部站点导航至URL时使用相关的cookie避免需要多次进行登录,目前大多数浏览器正在将SameSite属性迁移至Lax。
  3. 验证Referer:
    HTTP Referer是header的一部分,告诉服务器该请求是从哪个页面链接过来的,如果是第三方的页面则服务器可以拒绝相关的请求

本文只是简单重温了一下相关的知识点,大家有兴趣的话可以参考以下两篇文章进行更深入的学习:

PS: 欢迎看机会的同学们找本酱内推呀,我在字节跳动等你~