前端安全13条,除了XSS、CSRF这2条你还知道几个?

2,422 阅读13分钟

大家好,我是沐华。最近面了一些前端,发现每次问到安全相关的问题,一些面试者只能说上来 XSS、CSRF、中间人攻击,就没了,于是写了这篇文章,总结了前端安全相关的点,给大家查缺补漏

浏览器

XSS

XSS 攻击是一种代码注入攻击,通过恶意注入脚本在浏览器运行,然后盗取用户信息。本质上其实是因为网站没有过滤恶意代码,与正常代码混在一起之后,浏览器没有办法分辨哪些是可信的,然后导致恶意代码也被执行

结果是可能会导致:页面数据或用户信息被窃取、伪造登录窗口或在页面生成浮窗广告、监听键盘事件窃取账号密码、流量被支持到其他网站等

XSS 攻击有三种类型:

  1. 存储型:通过输入框把恶意代码提交到网站数据库中,然后比如在显示评论的页面就会从数据获取,并直接执行
  2. 反射型:和存储型不同的是不会储存在服务器里。比如打开包含带恶意脚本的链接,当打开后会向服务器请求后,服务器会获取URL中的数据然后拼接在HTML上返回,然后执行
  3. 基于DOM型:是通过一些劫持手段,在页面资源传输过程中劫持并修改页面的数据,插入恶意代码

防范:比如对输入框内容进行过滤和用转义符进行转码、添加白名单、关闭 Cookie 访问权限、使用验证码防止脚本伪装成用户执行操作等

CSRF

CSRF 就是跨站请求伪造攻击,主要就是利用用户的登录状态发起跨站请求

比如邮箱里的乱七八糟的链接,打开链接的时候邮箱肯定是处于登录状态,然后黑客就可以用这个登录状态,伪造带有正确 Cookiehttp 请求,直接绕过后台的登录验证,然后冒充用户执行一些操作,本质是利用 Cookie 在同源请求中携带发送给服务器的特点,来实现冒充用户

发起 CSRF 攻击有几个必要条件:

  1. 目标网站一定要有 CSRF 漏洞
  2. 用户登录过目标网站,并且浏览器保存了登录状态
  3. 需要用户主动打开第三方站点

CSRF 攻击也有三种类型:

  • 自动发GET类型:比如imgiframe标签等,当用户打开这个网站时会自动发起带 Cookie 的资源请求
  • 自动发POST类型:比如整一个隐藏的表单,在用户进入页面的时候自动提交表单
  • 诱导链接型:就是诱导用户主动点击链接,比如a标签

防范:比如 Token 验证、双重 Cookie、通过 origin/referer 验证请求来源等

CSP

CSP 就是白名单,作用是可以禁止加载外域的代码,禁止外域的提交,只允许本域下的请求表单提交之类的,简单说就是告诉浏览器哪些资源可以加载执行,让那些真的插入进入的恶意代码也不会被执行;或者允许向哪些第三方站点提交数据,因为攻击者窃取信息的根本还是向外域提交

开启 CSP 的方式有两种

1. meta

<meta http-equiv="content-security-policy" content="policy">
<meta http-equiv="content-security-policy-report-only" content="policy">

2. http response header

如果不支持 Content-Security-Policy,可以用 X-XSS-Proterction 代替

# 所加载的内容必须来自同源站点
Content-Security-Policy: default-src "self"
# 添加可信域名
Content-Security-Policy: *.baidu.com
# 和上面同理
Content-Security-Policy-Report-Only: policy

HSTS

HSTSHTTP 严格传输安全协议,作用是强制客户端使用 https 与服务器建立连接,以避免因为 http 而被中间人攻击

HSTS 设置须添加在请求头中,如下

Strict-Transport-Security: max-age=12345;includeSubDomains;

参数:

  • max-age: 指定该设置过期的时间,单位毫秒
  • includeSubDomains: 可选参数,表示所有子域名也必须通过 https 访问
  • preload: 可选参数,可以设置一个使用 https 的域名列表

设置 HSTS 后,再使用 http 访问时,只要 max-age 没有过期,客户端内部会进行跳转,会出现 307 Redirect Internel 状态码,变成 https 后,再访问请求的资源服务器

X-Frame-Options

X-Frame-Options 是用于控制当前页面是否可以被嵌入到 iframe 中,以防盗链及点击劫持攻击

X-Frame-Options 设置须添加在请求头中,如下

X-Frame-Options: DENY

参数:

  • DENY: 不允许,同域名嵌套也不行
  • SAMEORIGIN: 允许同域名嵌套
  • ALLOW_FORM url: 可以指定允许嵌套访问的来源

设置 X-Frame-Options 后,可以确保我们的网站没有被嵌入到别人的站点里去(以防内容被恶意嵌套,并且在表面加一个透明层,诱导用户点击),从而避免点击劫持攻击及恶意盗链

SRI

SRI 指子资源完整性,该方案的作用是确保我们站点的资源文件永远不会被改变,如果被改变,浏览器会拒绝执行

比如我们打包的时候有一个 xxx.js 文件,被 index.html 引用,并上传 CDN,用户在访问的时候,会去请求 xxx.js,而这个文件可能被劫持篡改,或者由于网络等原因,接收到的文件不完整,怎么办?

而设置了 SRI 就可以确保当请求的文件被篡改或不完整的时候就拒绝执行该文件,设置如下:

<link href="https://xxx/x.css" intergrity="sha1/asdhfkjasdf">
<script src="https://xxx/x.js" intergrity="sha1/asdhfkjasdf"></script>

标签上的 intergrity 属性值的格式是:哈希算法/base64后的哈希值

原理:

打包的时候会根据文件内容生成 hash,并且把 hash 作为 intergrity 属性注入到标签上,客户端接收到文件后,根据文件内容生成 hashintergrity 上的进行对比是否一致,如果不一致就会认为是不安全的,拒绝执行

Referrer-Policy

Referrer-Policy 是一种 HTTP 安全方案,用于控制 referer 携带策略,用于监管哪些访问来源信息会在 referer 中发送

注意 referer 实际上是单词 referrer 的错误拼写。而 Referrer-Policy 这个首部并没有延续这个错误拼写

开启 Referrer-Policy 的方式有两种

1. meta

<meta name="referrer" content="same-origin">

2. http general

Referrer-Policy: same-origin

参数:

  • no-referrer:不发送 referer
  • no-referrer-when-downgrade:默认值,同安全级别发送 referrer 并且是完整 url,不同安全级别则不发送
  • origin:只发送协议、域名、端口,不发送完整 url,比如 https://juejin.cn/index.html,会变成https//juejin.cn/
  • origin-when-cross-origin:同源才发送完整 url,不同源只发送协议、域名、端口
  • same-origin:同源才发送 referer,并且是完整的 url
  • strict-origin:同安全级别和 origin 是一样的,比如 https 请求 https,如 https 请求 http 是不同安全级别了,就不发送
  • strict-origin-when-cross-origin:同源发送完整 url,同安全级别才发送协议、域名、端口,不同源或不同安全级别不发送 referer
  • unsafe-url:这是最不安全的策略,不管同不同源都发送完整 url

HTTPS

由于 http 是明文传输,是不安全的,所以在 http 传输过程中信息可能被窃取、伪造、篡改,这种攻击方式被称为中间人攻击

避免中间人攻击的方法就是用 https,在应用层与传输层之间添加一个安全层 TLS,但也不是就绝对安全了

安全层会通过加密算法和公钥私钥加密传递的数据,好处是即使被劫持,中间人没有私钥就拿不到加密生成的随机数,就无法生成最终密钥

但问题是:假如一开始就被 DNS 劫持,或者说域名劫持攻击,拿到的公钥就是中间人的,中间人解密拿到数据后,再请求实际服务器,拿到服务器公钥,再把信息发给服务器,这样不知不觉间信息还是会被窃取

所以,还需要搭配数字证书,来帮我们验证服务器身份。可 https 还有一个安全问题就是伪造证书的存在,比如

  • 比如 CA 机构没有正确校验申请者的身份而无意签发了一些错误的证书
  • 比如 CA 机构在利益的驱使下,发放的证书
  • 比如冒充或伪造某个域名的拥有者,申请到一张证书,毕竟域名拥有者是无法知晓哪些 CA 机构给他签发了证书,也不知道是否有人冒充他的身份申请了证书的
  • ...

CA 证书公钥可信度是靠操作系统里面预置的 CA 证书公钥列表来保证的,就像白名单,用户一般也不知道 CA 证书公钥的真假,那如果有黑客有能力把自己的公钥放到用户系统的 CA 证书公钥列表里,那也可以伪造数字证书放到用户的电脑上,而用户却无法感知就信任了这个证书,然后你懂的

为了解决证书问题,有一个解决方案,就是证书透明度(CT),能够审计、监控证书的签发和使用,一旦发现伪造的证书,可以快速联系到 CA 机构,吊销该证书

使用证书透明度服务就是添加请求头 Expect-CT 用来告诉浏览器期望使用证书透明度服务的,这能更有效的避免中间人攻击等

但谁也不能说这就有 100% 的绝对安全了,只是现行架构下的这些解决方案,已经大大增加了中间人的攻击成本,一般都是可以放心的

Node(服务端)

本地文件操作

指由于本地文件操作相关或路径拼接导致的文件资源泄露,所带来的安全问题

  • 比如提供了一个静态服务,通过请求的参数 url 来给客户端返回想要资源,而用户手动修改 url 上的路径却可以访问到
  • 比如暴露了一个服务或接口也可以操作文件的话,如果对它的校验不是那么安全的,就会有攻击者能访问到我们的文件,比如 ssh 文件、密码之类的

预防:express-statickoa-staticresolve-path,都可以解决这个

WebShell

WebShell 是指一种恶意脚本,或者脚本木马

原理:

利用文件上传漏洞、SQL注入漏洞等等,把恶意文件放到服务器中,作为后门,然后通过服务器开放的端口+后门获取服务器的操作权限,比如窃取用户数据、修改权限、文件管理 修改甚至删除 web 页面、数据库管理等等

常见的 WebShell 编写语言是 jsp、asp、php

攻击方式:

  • 上传漏洞。网站上有上传文件的功能,过滤又不严,就可以直接把 jsp、asp、php 文件直接上传到服务器
  • 上传文件类型。项目上有添加上传类型或重命名文件功能的,比如把 WebShell 文件重命名成.jpg之类的允许上传的文件,上传完成后,再重命名改回如 .jsp 这样类型的文件
  • 隐藏到合法文件。比如把 php 代码放到 jpg 文件里,再使用@运算符防止发生错误,或者删除空格换行等,导致代码比较混乱,再使用编码或者加密来隐藏恶意函数等
  • 隐藏到日志。修改发送数据包的头部,添加 WebShell 。 web 服务器一般会保存访问记录到Web日志,如果找到web日志,且放到可执行目录下,可能获得 shell
  • .....

ReDos

ReDos 就是正则表达式攻击,利用正则表达式攻击或者利用开发者正则写的不规范,而疯狂占用服务器资源,造成服务器宕机

正则表达式匹配规则是:会先匹配第一种要能性,每当一次匹配不成功,就会尝试回溯到上一个字符,看看能不能有其他组合来匹配到这个字符串,比如,匹配 aaa 会向下面这样匹配

aaa
aa + a
a + aa
a + a + a

再看下图三条正则表达式执行时间,第一条 0.198ms,第二条 26.445ms,第三条没有结果,因为跑不完,会一直疯狂占用资源

时序攻击

时序攻击由于条件非常严荷,所以了解一下即可,哪怕只能说出时序攻击这四个字,但知道有这么回事就比不知道的强

比如攻击者尝试 arr = [1,2]arr = [1,3],发现响应时间几乎一致,则可以认为第一个数字不是 1,再尝试 arr = [2,1],依此类推,不断碰撞尝试,直到最后碰撞出来真实的 arr

像是对比两个数组是否相同,下面代码看似没什么问题,业务效果完全能达到,但是在绝对安全层面上是不安全的

当然业务代码中没必要这么严苛,因为比如上述代码上如果还有其他 if else 判断,就完全没办法碰撞出来了

爬虫

爬虫就是一种按照一定规则自动抓取资源的程序或者脚本,搜索引擎可以用爬虫抓取网页、图片、视频、音频等

对于有一些没有防范的系统,通过爬虫,甚至可以把人家会员才能看或者付费下载的资源直接给爬下来,假设网站上有一个 10MB 的文件,使用爬虫抓取上千上万次,就会导致网站产生大量出站流量,很可能还会使服务器瘫痪无法访问了

防范其实主要就是服务端安全校验的问题,比如设置 robots.txt 文件、比如对请求中的 User Agent 识别和限制,说到底防爬虫主要是防范这几个点:iporiginrefererrequest headers

如果没有并发的去请求去爬虫的时候,它不会针对 ip 做校验,只会判断后面几个,而如果没有后几点就会认为你是不安全的系统,就给爷爬

结语

如果本文对你有一点点帮助,点个赞支持一下吧,你的每一个【赞】都是我创作的最大动力 ^_^

更多前端文章,或者加入前端交流群,欢迎关注公众号【沐华说技术】,大家一起共同交流和进步呀

往期精彩

【保姆级】Vue3 开发文档

TS 泛型进阶

深入浅出虚拟 DOM 和 Diff 算法源码,及 Vue2 与 Vue3 中的区别

上手 Vue 新的状态管理 Pinia,一篇文章就够了