You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
10 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 29Session与Cookie账户体系的安全设计原理
你好,我是王昊天。
我有次在访问某个页面时为了下载一些东西按照页面要求进行了复杂的登录操作。之后我不小心关闭了当前页面然后再一次点开这个页面麻木的准备再来一遍复杂的登录操作时我神奇地发现面前的Web应用竟然是登录成功的状态你知道这是怎么一回事吗
事实上,这个现象是**由Web账户体系的安全设计所导致的**。在这一讲中,我们将会对它进行学习,这样你就能清楚地知道问题的答案啦。下面我们就正式开始今天的学习。
现在几乎每个大型Web应用都会存在账户体系当我们需要获取Web应用中的某些服务时Web应用会首先对我们的身份进行认证。所以接下来我们会从身份认证的相关基础知识入手。
## 身份认证
身份认证的方式有多种我们可以用最典型的账号密码进行认证除此之外我们还可以用cookiesession、Token、数字证书以及手机验证码来验证。这里你可能对于cookie以及Token会比较陌生不过不用担心我们会在后面对它们进行详细的讲解。
![图片](https://static001.geekbang.org/resource/image/23/32/2335013cf74e33de8a633f9e19ed9432.jpg?wh=1530x562)
在这些认证过程中,可以分为两种类型,即**登录过程的认证以及保持登录的认证**。
为了让你更好地理解它们二者之间的区别,我们一起来看一个示例。
![图片](https://static001.geekbang.org/resource/image/36/57/3687aa08f5f4b0d079a5c65101e45757.png?wh=1514x1558)
这是谜团mituan.zone的登录页面我们需要输入正确的用户名、密码以及验证码才能通过身份认证很明显这是登录过程的认证。
当我们登录成功后我们会发现浏览器中多了一些cookie信息。
![图片](https://static001.geekbang.org/resource/image/65/bd/65a34fa6b6ec03cf8da34a5027f4bebd.png?wh=1920x1339)
这些cookie信息有一定的有效期。在有效期内cookie信息会一直存在它使得我们下次访问这个页面时无需再次输入账号密码进行登录而是**可以直接用cookie信息来实现身份认证操作**,这就是保持登录的认证。
你现在知道导入中神奇现象发生的原因了吗?其实在导入部分中的自动登录,就是通过保持登录的认证来实现的。而这种认证方式,主要是通过会话管理来实现的,接下来让我们简单了解下会话管理的作用。
## 会话管理
在学习会话管理之前我们首先需要巩固下HTTP协议的知识。
HTTP协议是无状态无连接的协议服务端对于客户端每次发送的请求都认为它是一个新的请求上一次会话和下一次会话是没有联系的。因为它无法保存登录状态所以从协议本身来说它不适合用来做会话管理。
因此,**我们会使用一个上层应用去实现我们的会话管理功能**。这个应用可以在切换页面时保持登录状态,并且对用户是透明的,这样就使得我们能在短时间内再次访问一个登录过的页面,就会保持登录状态。
经过上述内容的学习你已经知道了会话管理具有什么作用。接下来让我们具体学习下会话管理的两种典型方式即基于session的认证以及基于Token的认证。
### 基于 session 的认证
Web应用可以基于session的认证来实现保持登录它的具体实现方式如下图所示
![图片](https://static001.geekbang.org/resource/image/ee/39/ee235b45ccaa03df9d199b16372d9739.jpg?wh=1373x827)
用户在首次访问Web应用时会将自己的账号密码通过POST方式进行上传然后Web应用服务器会对账号密码进行检查。如果检查通过就会给用户配置一个sessionid并将它存储在服务器内存中之后再把这个sessionid发送给用户。
注意这里sessionid的位置可能在URL、隐藏域以及cookie中。由于cookie信息较为隐蔽些所以**将sessionid放在cookie中相对来说更为安全**,因此这一实现方式也最普遍。
用户在收到Web应用服务器的回应之后再次对Web应用发起请求的cookie中就会自动包含sessionid信息。Web应用服务器会对其中的sessionid信息进行检查以获取用户的登录信息如果信息正确就让用户处于登录成功的状态否则需要重新进行登录过程的认证。
值得一提的是为了安全考虑Web应用通常会**给sessionid设置一个过期时间**使得sessionid仅在某个时间段内有效这样就可以有效地抵御攻击者盗用sessionid绕过身份认证的行为。
到这里我们已经学习了Web应用是如何利用session进行身份认证的。而这里还有一个很重要的知识点我们有必要深入了解一下那就是在session进行身份认证中存在的典型攻击方式——**会话固定攻击**。
在之前的学习中我们知道了sessionid可以存在于URL中。在这种情况下如果登录前后sessionid不变化那么攻击者就可以发起会话固定攻击。
这里我已经画出了会话固定攻击的示意图,让我们一起看看吧。
![图片](https://static001.geekbang.org/resource/image/3a/17/3a3a745cbbf606f45b3a3a257a7c8417.jpg?wh=989x579)
攻击者首先访问一个需要登录的网站获取到Web应用返回的sessionid信息。由于攻击者没有账户密码所以只能通过发送一个诱骗信息给受害者使得受害者用这个sessionid实现登录操作。这样攻击者的sessionid就通过了验证使得攻击者再次用这个sessionid信息访问被攻击网站时可以直接通过保持登录的认证。
这就是将sessionid信息放在URL中的安全隐患。
### 基于 Token 的认证
除了基于session的认证之外Web应用还可以利用Token来实现会话管理。
基于Token的认证方式如下图所示让我们从图中观察它是如何实现的吧。
![图片](https://static001.geekbang.org/resource/image/e3/1c/e33ae83a0b7ce74f0e9f492e9d10df1c.jpg?wh=1333x790)
用户首先需要通过POST方式上传账号密码信息进行登录过程的认证Web应用服务器接收到之后会检查账号密码信息是否正确如果正确就会生成一个包含密码信息的Token值这里以JWTJSON Web Token为例。
之后服务器会将这个Token信息发送我们的浏览器接着浏览器会将这个Token信息保存在Header中使得以后每次请求的Header中都会包含这个Token信息。服务器在接收到Token信息后会从中提取出用户的账户信息并对此进行检测然后将响应发送给我们的浏览器。
这就是基于Token的认证方式下面让我们以JWT为例进行学习深入地了解Token的具体形式。
![图片](https://static001.geekbang.org/resource/image/3f/04/3fe009b99457992b08174b7290136f04.jpg?wh=1352x589)
上方方框中的内容是一个完整的JWT信息它可以根据.分割成三个部分,我们将它不同的部分用不同的颜色进行显示。**接下来让我们逐一分析JWT各个部分的内容。**
第一个部分经过base64解码就变为了蓝色方框中的内容其中alg的内容设置的是signature中签名使用的算法而typ的内容则定义了这个Token的类型。
第二部分解码为绿色方框中的内容它包含了用户相关的信息Web应用可以根据这些信息来确定用户的身份。
最后一部分解码为橙色方框中的内容它包含了对Token信息的完整性验证签名。其中需要用到仅有服务器知道的secret信息这也是导致攻击者无法伪造Token信息的关键。
**以上就是JWT的组成结构。**其中Header以及payload用到的都是些通用数据攻击者很容易就可以伪造出来。唯一有难度的就是对secret签名部分的伪造事实上攻击者可以通过密钥爆破的方式尝试进行Signature信息的伪造。一旦伪造成功攻击者就可以以任意身份登录这个Web应用这对Web应用来说是极大的威胁。所以Token信息的设计者需要有意识地提高secret的复杂度。
到这里,你已经学习了会话管理的两种典型方式。接下来,让我们拓宽视野,简单了解下单点登录的知识。
## 单点登录
如今的Web应用越来越多同一个公司可能就会研发出多个Web应用如果每个应用都需要分开登录注册那既会使得用户感到不方便也会增加开发成本。为了解决这个问题大家通常会采取单点登录方案。
单点登录就是**用户只需要登录一次就可以访问所有相互信任的应用系统**。它把认证的流程统一起来,使得认证的风险集中化。
![图片](https://static001.geekbang.org/resource/image/8e/30/8e6050a4ffa8942cde1005d44eafb030.jpg?wh=1021x713)
这样,我们只需要在那统一的登录流程中**做好安全认证措施**,就可以实现对多个应用的身份认证。单点登录既能降低开发成本,也可以提高登录的安全性。
## 总结
这节课我们学习了账户体系的安全认证设计。
首先,我们学习了身份认证的方式,了解到除了我们熟悉的登录过程认证之外,还有保持登录认证这一种方式。
接着我们深入学习了保持登录认证的方式知道了它是由会话管理方法实现的。然后我们对基于session的会话管理以及基于Token的会话管理进行了全面的学习我们不仅知道了它们保持登录认证的实现方式还知道它们存在的安全隐患。
最后我们了解了一个面对多个应用需要登录验证时的解决方案即单点登录。使用单点登录既可以统一管理所有的登录认证还可以降低多个Web应用的开发成本。
## 思考题
你知道在基于session的保持登录认证中为什么将session信息放置在cookie中会更加安全吗
欢迎在评论区留下你的思考。如果觉得今天的内容对你有所帮助的话,也欢迎你把课程分享给其他同事或朋友,我们共同学习进步!