Cookie,Session,Token,同源策略、跨域、XSS、CSRF、DNS劫持一次性搞明白

1,247 阅读9分钟

前端安全--用户身份标识

这是一块很多、很杂、而且关联性很强、难以理解的知识。这次把这块知识总结一下,彻底理清楚之间的逻辑关系。本文是我后期复习的复盘,有部分基础的知识可能没有详细讲解。

Cookie

为什么会出现cookie

由于HTTP是无状态的,也就是说服务器在收到请求之后,不知道是哪个客户端请求的,这样无法满足有些场景,比如下面这个场景

   客户端添加购物车、去结算、下单,再添加购物车之后,服务端需要为该用户的购物车数据库中添加商品,去结算要为该用户生成订单,所以服务端会知道是哪个用户发来的请求。

于是cookie出现了,它是客户端的一小段存储空间(4KB),是存储空间!!!

我们在浏览器中的application选项卡中可以看到。注意,cookie是服务端通过set-cookie这个http响应头设置的!下面是我截取来自掘金的一段cookie,下面的字段没有一个不重要的:

image.png

set-cookie字段解释:

标题namevalueDomainsize
字段含义cookie的名字cookie的值访问这个域会被带上cookie长度

SameSite

有三个值:strict Lax None(必须带上Secure),常用来预防CRSF(后面说)

HTTP-only

限制不能通过JS读取到该cookie,预防XSS攻击(后面说)

Expires

cookie的过期时间,绝对时间,就是说几点几分几秒这个cookie就过期了,HTTP1.1之前使用Expires,那老技术肯定就有问题:

1.客户端服务端时钟不一致,

2.服务端需要计算出一个具体时间,服务器压力大

Max-age

相对时间,几个小时之后cookie就过期了。这个好!但是HTTP1.1才提出,旧浏览器不兼容。

Session

为什么会出现Session

Cookie很重要,因为它标识用户的身份,想想如果别人拿着你的cookie就可以登录淘宝,去把你购物车清了!所以一定要保护好,虽然有HTTP-only,SameSite等一系列预防的手段。但是将这么重要的东西存在浏览器,总归是不安全的,所以就出现了session。

Session是什么

session顾名思义,会话。当用户访问服务器,就开始了一次会话,这个时候服务器为用户生成一个session(会话),sessionID 表示这个会话的唯一标识。服务端将sessionID返回给浏览器,浏览器存储到cookie中,下次访问Domain下的域名时会带上。服务器通过sessionID判断用户的身份。

当用户关闭浏览器,会话结束,浏览器会删除sessionID,服务器会保持一段时间,防止用户短时间再次访问服务器。

session会有什么问题?

1 如果用户多,服务器存储压力大。

2 由于负载均衡,用户的请求可能会被分配到不同的服务器,这个时候会存在访问到的服务器不存在该用户session的情况,需要做服务器之间的session同步。

Token

token是用于做用户身份验证,但是它是明文传输的,它唯一的作用就是防止篡改。token可以存在cookie中,也可以存在localstroage中,不care。

Token的构成如下所示(以JWT为例): 由三部分组成:Header、payload signature。不熟的同学去看一下。

Header和payload是明文传输,只是base64编码,很容易就解码, signature是将前两者通过加密算法和密钥来生成的,是为了防止篡改的!!服务端收到token之后拿着自己的密钥来解密,获取到Header和payload(可能是对称加密也可能是非对称加密(不懂的参考HTTPS))

总结

cookie是浏览器的一小块存储空间,session是为了解决cookie不安全的问题出现的,但是又造成了新的问题。token是用来做身份校验的令牌,他跟前两个压根就不是一个维度的东西。JWT是token的一种。上面这三个

前端安全--浏览器策略

因为各种攻击的存在,浏览器需要制定一定的策略,那么这个策略就是同源策略。

同源和跨域

同源是指两个URL的协议、域名、端口号都相同,浏览器在当前所处的域下(就是你目前在看的这个网页),去访问跨域的资源(协议域名端口号不同的资源),就会发生跨域,请求不到资源,浏览器报错。HTTP实行同源策略,websocket不实行,不存在跨域的问题。

可能的误解

1.浏览器只会对AJAX请求做出跨域限制?

错误:浏览器对于JS、图片、AJAX都会做出限制,只是对AJAX的限制比较大,所以一般谈到跨域人们会认为是对AJAX的限制

2.如果一个请求跨域了,浏览器就不会发送这个请求了?

错误:请求还是照样发,而且服务端资源还返回了,但是浏览器会在最后一道关卡做拦截,不会呈现到页面,比如跨域的图片不呈现,跨域的脚本不执行。

跨域的解决方法

因为讨论的是安全问题,这部分不细说,主要有以下几个方法:

1.CORS:服务端配置Access-control-Allow-Orign响应头,允许访问的客户端,配置*表示允许所有的client访问。

2.正向代理服务器:客户端自己使用nodejs搭建一个服务器,由于服务器之间是不存在跨域的!我只需要访问我自己的服务器,服务器去与资源服务器要资源就行。

3.反向代理nginx:原理跟2一样,只是服务器是后端那里配置的,隐藏服务器的身份。

4.JSONP:一种很巧妙的方式,利用浏览器对script标签限制小的特点。因为这个要会手写,所以就不讲了。不会写的可以去看一下。

5.websocket:这个使用的是ws,wss,该协议不实行同源策略。

6.iframe是一个HTML元素,它允许您在当前网页中嵌入另一个网页。我们引入iframe网页将document.damain设置相同可以解决跨域。

前端安全--网络攻击

CRSF(跨站请求伪造)

整个流程

1.用户访问银行网站,银行网站a.com会返回一个cookie给用户,cookie存储在浏览器端,下次作为用户的身份标识。

2。用户没有退出银行网站(cookie一直在),用户点击了恶意链接b.com,b.com会向a.com发起一个请求,这个请求往往会携带一些操作,比如转账。

3.因为用户已经有a.com的cookie了,所以浏览器压根就直接转发b.com的请求,a.com服务器收到请求,校验cookie,发现是用户发来的请求,所以就执行转账操作。

4.用户整个过程不知情,只是点击了一个链接。

疑虑

1.为什么b.com请求a.com不会跨域?

浏览器的同源策略禁止了不同域名下的资源共享,但是它不禁止跨域请求,只是发起一个请求,不是要返回资源,CRSF攻击者的目的是自定义的操作。

2.CRSF的本质是什么

攻击者利用用户已经访问的凭证(cookie)、浏览器会自动带上cookie、服务器只校验cookie这三点,骗过了服务器,用户完全不知情。

解决办法:

1.同源检测

服务端对HTTP请求头中origin的referer做检测,判断请求是不是允许访问的域。

2.为cookie设置SameSite属性

SameSite设置为Lax或Strict,一般都是Lax。

3.CRSF Token

解决cookie单一验证的方式,服务端生成token返回给客户端。客户端在下次请求的时候在HTTP请求头里带上这个token,然后服务端session里面存了token可以做校验,但是会有负载均衡的问题,请求可能会被分配到没有相应token的服务器。

4.双重cookie

为了解决CRSF token服务端存储的压力,所以采用双cookie,将cookie在请求域名中带一个,服务端比较两者是不是一样。利用攻击者无法获取cookie,也就无法在URL中添加cookie。服务端校验不通过。

XSS(跨站脚本攻击)

反射型

场景1.恶意攻击者在input框输入下面的代码:

 `http://xxx/search?keyword="><script>alert('XSS');</script>`   

服务端将恶意代码拼接到HTML中返回,浏览器执行,恶意代码执行,可能是获取用户的cookie。

解决办法

对敏感字符做转义比如大于小于引号

场景2.a链接中输入javascript开头的代码

<a href="javascript:alert(&#x27;XSS&#x27;)">跳转...</a>

转义已经无济于事,采用白名单机制,限制a链接中出现javascript开头的代码

存储型

场景 发表评论

用户发表评论,含有恶意代码,存储到后台数据库,当其他用户访问该评论,数据库就会返回恶意代码执行,比如获取cookie。

DOM型

场景

用户在input输入恶意代码,前端JS拿去执行了。比如vue中可以双向数据绑定,拿到用户输入,v-html这个就可能造成XSS攻击。

解决办法:规范前端代码

XSS的解决办法

1.字符过滤与转义

对输入的敏感字符进行过滤或转义,浏览器就不会把这些字符当代码执行,而是当成文本。需要注意转义规则和转义时机,转义太严格,正常代码被转义导致乱码,转义太宽松,恶意代码未被转义,造成安全隐患。

转义时机有以下三个:用户输入,写入数据库时,前端呈现到页面时。之前转义可能会被多次转义,而且出现页面呈现错误的情况。最好在呈现页面时转义最好用成熟的转义库,不要自己写转义规则。

2.CSP 白名单策略

CSP(内容安全策略)实质就是白名单策略。开发者明确告诉客户端,哪些外部资源可以被加载和执行。就是网页上的保安。

3.保护cookie

为cookie设置HTTP-only属性,保证它不会被JS读取。

DNS劫持

这个是违法的。就是通过一些手段将用户的域名访问劫持 返回错误的 ip 地址 给用户返还自己恶意服务器上的资源。轻则返回一些广告 重则做一个克隆网站 用户以为是真的 然后输入敏感信息被盗号。

一个良性DNS劫持--CDN

用网上的一张图: image.png

image.png