cookie和token

原文地址:Demystifying cookies and tokens – Tommi Hovi | The Security blog

Cookies

Cookie是由您访问的网站(网络服务器)创建并存储在您设备中的小型文本文件。我们都遇到过他们。实际上,您访问的每个网站都是用cookie横幅“问候”您。cookie的用途取决于cookie的类型以及网站希望cookie做什么。例如,在线商店可以使用cookie来跟踪用户在其网站上的移动、他们访问的最后一个页面是什么、您选择了什么语言、用户查看了什么项目以及他在购物车中放置了什么商品。当用户离开网站但稍后返回时,网站可以读取cookie,例如从用户离开的地方继续。但并非所有cookie都有相同的目的。

为什么我们首先需要Cookie?我们需要Cookie,因为HTTP是一种无状态协议。HTTP不记住客户端会话信息,因此客户端负责使用cookie存储该信息。对于某些网站,无状态行为可能是可以的,也许网站在用户会话期间不应该保留任何元素或用户操作。但对于大多数交互式网站来说,Cookie是必要和必不可少的,我们作为网站访问者,也希望网站以某种方式运行。非常感谢Cookie,这使它成为可能。当客户端向Web服务器请求网站时,Web服务器会响应“200 OK”,并使用Set-cookie标头向客户端发送cookie。cookie包含会话ID,通常还包含其他属性。Web服务器还跟踪站点在服务器端分发给客户端的会话ID。

Cookie主要用于:HTTP会话管理、个性化、追踪。

Cookie存储在您的浏览器上。更确切地说,它们存储在硬盘上浏览器的临时目录中。存储Cookie的确切位置和方法取决于浏览器和操作系统。您通常会通过浏览器界面进入设置来管理Cookie。通常,您会使用浏览器的界面来管理、查看或删除Cookie。

Cookie属性

  • Session ID  是一个唯一的随机字符串,用于标识和匹配客户端和Web服务器之间的会话
  • Expires  定义cookie设置为过期的日期
  • Domain  指定cookie有效使用的一个或多个域
  • Path  指定cookie有效使用的资源或路径
  • HttpOnly  启用HttpOnly后,将阻止JavaScript等客户端API访问cookie。这减轻了跨站脚本(XSS)的威胁。
  • Secure  启用安全时,将要求仅使用HTTPS发送cookie,而不允许使用HTTP等未加密的连接,这使得cookie不易被窃取。
  • Session 会话定义cookie是一个临时cookie,在浏览器关闭时过期
  • SameSite 可以有严格、宽松或无值
    Strict = 浏览器仅向与源域相同的目标域发送Cookie
    Lax = 浏览器向目标域发送Cookie,即使它与源域不同,但仅用于安全请求(如GET),而不是第三方Cookie。
    None = 允许第三方Cookie(跨站点Cookie)

cookies的类型

必要cookies

必要Cookie是网站正常运行所必需的,通常会使用户的浏览体验更加方便。

  • 会话Cookie
  • 第一方Cookie
  • 身份验证Cookie
  • 以用户为中心的安全Cookie
  • 用户输入Cookie

会话cookie(又称非持久cookie、内存cookie、瞬态cookie)
会话cookie是临时cookie文件,当用户关闭浏览器或其会话处于非活动状态时(如果用户注销,会话将结束),这些cookie文件将被删除。它们是单会话Cookie。当用户重新启动浏览器并返回创建cookie的网站时,网站将无法识别用户,因为网站没有cookie可以在用户的浏览器中读取。用户必须重新登录(如果需要登录网站)。登录后,将生成一个新的会话cookie,该cookie将存储用户的浏览信息,并将一直处于活动状态,直到用户离开网站并关闭浏览器。由于会话cookie有自己的唯一id,它也可以用于跟踪网站访问者数量。如果您计划度假旅行,并且每天多次访问旅行社的网站,cookie的会话ID将向网站显示您只是一个唯一的访问者。

第一方Cookie(即持久Cookie、永久Cookie、存储Cookie)
第一方cookie将保留在浏览器中,直到用户删除它们或浏览器根据持久cookie文件中包含的持续时间删除它们。这种类型的cookie可以用其他术语来指代,如持久cookie、永久cookie或存储cookie,因此它们在单个会话中具有持久性。如果在此期间未访问该网站,大多数第一方Cookie将在1-2年内过期。cookie过期后,浏览器将自动删除它们。第一方cookie最为人所知的是为用户提供服务,以保持他们的帐户登录到网站,从而避免每次访问网站时繁琐的重新输入凭据。

身份验证Cookie
身份验证Cookie是会话Cookie的变体。他们将在成功登录后识别用户,并在用户在内容授权给登录用户的网站上导航时携带该身份验证信息。例如,当用户向网上银行进行身份验证时,他们有权查看自己的银行账户余额。如果他们转到另一个页面查看贷款,身份验证cookie会确保用户现在必须为该页面提供新的身份验证。

以用户为中心的安全Cookie
以用户为中心的安全Cookie可以跟踪身份验证错误,并通过跟踪在登录页面上尝试错误登录凭据的次数来检测可能的身份验证滥用。

用户输入Cookie
用户输入Cookie是第一方会话Cookie,用于跟踪用户自己在网站上输入的操作和项目,如填写表单或单击某些按钮(如添加到购物车)。

非必要Cookie

非必要的Cookie对于用户的浏览体验或网站的正常运行不是必需的。

  • 分析和定制Cookie
  • 广告Cookie
  • 第三方Cookie
  • 超级Cookie

分析和定制Cookie
分析和定制Cookie跟踪用户活动,以便网站管理员更好地了解他们的网站是如何被使用的。网站管理员可以用来增强网站的一个分析示例是,网站上的一些信息可能真的很“冷”,这意味着用户很少打开该页面(不感兴趣)或无法进入该页面。

广告Cookie
广告Cookie仅用于定制用户在网页上看到的广告。他们使用用户的浏览历史来使广告“更相关”。这就是为什么我们开始看到关于我们以前搜索过的东西的广告。

第三方Cookie(也称为跟踪Cookie)
第三方Cookie是我们不喜欢的Cookie,也是Cookie声誉如此糟糕的原因。第三方Cookie来自用户访问的不同域,因此它们不提供会话Cookie或第一方Cookie的任何好处。这些Cookie仅用于一个目的,即跟踪您。

超级Cookie
从技术上讲,超级Cookie不是Cookie,在某些情况下不会存储在用户的设备上。“普通”cookie最多可以保存4KB的数据,而超级cookie可以保存100KB的数据。超级Cookie具有与跟踪Cookie类似的功能,但它们的控制方式与其他Cookie不同。在某些情况下,超级cookie存储在浏览器缓存中,某些形式的超级cookie被注入到ISP仅控制的UIDH(唯一标识符标头)中。由于超级cookie的性质,它们更难识别,对于UIDH超级cookie,您无法清除它们。

tokens

令牌是用于信息交换的自包含且紧凑的JSON对象。一个典型的令牌是JSON Web令牌(JWT),用于客户端(应用程序)和另一个服务(如Web服务器)之间。细节取决于确切的身份验证流程。

与存储用户在网络会话中短期或长期活动信息的Cookie不同,令牌在软件之间传输信息。令牌中存储的信息取决于令牌的类型。例如,ID令牌携带有关已认证用户的信息。访问令牌通常包含有关安全主体及其授权访问的信息。这里是令牌和cookie相交的地方:一些令牌存储在客户端的本地存储或cookie中。出于安全原因,最好使用HttpOnly cookie。开发人员社区倾向于Cookie,因为本地存储被认为是不太安全的选择。同样值得一提的是,令牌被用作协议的一部分,并非所有令牌都是同一协议的组成部分。

我将在这里提到并简要解释的协议是OAuth 2.0和OpenID Connect(OIDC),因为它们被微软身份平台使用。

OAuth是Open Authorization的缩写,它是一种旨在处理代表用户访问资源的应用程序或网站的授权流的标准。简单来说,OAuth是一种主要用于web平台的授权协议。OAuth使用访问令牌,通常包括但不限于JSON Web令牌。Microsoft Identity Platform中的OAuth协议使用格式化为JWT的访问令牌(承载令牌)。OAuth 2.0授权流有多种不同类型。

OpenID Connect扩展了OAuth 2.0授权协议,因此它也被用作使用ID令牌的身份验证协议。OpenID Connect登录流用于获取ID令牌,该令牌被发送到验证用户身份的应用程序。

令牌解决的问题

让我们描述一个传统的身份验证和授权场景,其中令牌不存在。用户首先登录,web服务器通过检查其数据库中输入的凭据来对用户进行身份验证。一旦凭据匹配,服务器就会发出一个唯一的会话标识符并将其发送给客户端。用户的客户端将会话id存储在设备上。对于从客户端到服务器的每个后续请求,会话id都会在cookie或http请求头中发送。服务器需要从其数据库中再次查找会话id,以识别用户并检查授权级别。

上述场景的问题是,对于来自客户端的每个请求,服务器都需要往返数据库,这使得应用程序的使用速度变慢。

然而,使用令牌的场景通过发出包含用户信息和签名的JWT来解决后续的数据库查找问题,该JWT验证令牌内容的真实性。JWT被发送到客户端,客户端再次存储它。对于客户端向服务器的每个请求,客户端都包含JWT。服务器只需要验证令牌的签名以确保其真实性,当它签入时,服务器可以从令牌中提取身份和授权详细信息,而无需数据库查找。

令牌类型

  • ID token
  • Access token
  • Refresh token
  • Bearer token

ID token
ID令牌是通过OpenID Connect(OIDC)登录流程获取的,该流程是去中心化身份验证的开放标准。ID令牌必须采用JSON Web令牌格式。它们由授权服务器颁发给客户端应用程序。ID令牌包含有关用户或安全主体的声明,例如可以包含有关MFA状态的声明。客户端应用程序可以使用ID令牌中的信息和声明验证用户是否是他们声称的用户。默认情况下,ID令牌在Microsoft Identity Platform中的有效期为一小时。ID令牌不用于调用受保护的API。

Access token
访问令牌是由授权服务器签名的短期(JWT)令牌,使客户端能够安全地调用受保护的web API。访问令牌不需要格式化为JSON Web令牌,但在Microsoft Identity Platform中,它们是JWT格式的。访问令牌包含在从客户端到服务器的每个http请求中。这通常是通过使用“Bearer”模式的http请求中的Authorization标头发生的。这样做将避免服务器在每次请求时对用户进行身份验证。客户端将访问令牌存储在cookie或本地存储中。访问令牌旨在在服务器端使用。客户端不需要也不应该用于读取访问令牌的内容。

Refresh token
刷新令牌通常与访问令牌一起获取。它用于在之前的访问令牌到期时获取新的访问令牌,以及新的刷新令牌。客户端将访问令牌存储在cookie或本地存储中。刷新令牌的默认生存期为90天,单页应用程序除外,默认生存期是24小时。

Bearer token
不记名令牌是指任何拥有令牌的人都可以使用的代币。令牌持有者不必证明拥有加密密钥。把它想象成酒店房间的钥匙卡。如果你把钥匙卡放错了地方,而其他人拿到了它,他们可以用它进入酒店房间,而不需要证明他们是房间的合法所有者。

 

JSON Web令牌(JWT)

JSON Web令牌是一种标准化的对象,用于在双方之间安全地发送数据。为确保JWT的内容在传输过程中没有被更改或篡改,JWT使用加密密钥进行签名。这需要重复:JWT是签名的,不是加密的。签名验证数据的发送者,而加密将数据从明文转换为未经授权的接收者无法读取的密文。如果签名的令牌内容在传输过程中发生变化,公钥(用于对令牌进行签名的私钥对)将无法再验证签名。强烈建议在JWT中使用HTTPS等协议,以保护令牌内容在传输过程中的机密性。

JSON Web令牌由三部分组成:Header、Payload、Signature

JWT的安全问题
与任何技术解决方案一样,JSON Web Token也有其缺点。

大小限制和存储
一些复杂的应用程序需要在令牌中存储大量信息。当令牌存储在cookie中时,这可能会增加每个请求的开销,甚至超过cookie的允许大小(4KB)。当这种情况发生时,一种常见的解决方法是将JWT存储在本地存储中,该存储有其自身的安全问题,主要是页面内的任何脚本都可以访问本地存储中的数据。这可能会导致跨站脚本(XSS)攻击能够访问令牌。

一般来说,Cookie是由服务器读取的,而本地存储只能由浏览器读取。这意味着cookie仅限于比本地存储更小的数据量。当令牌存储在本地存储中时,浏览器会使用JavaScript访问它。这是存储在本地存储器中的令牌容易受到跨站脚本攻击的根本原因,因为攻击者可以将恶意JavaScript注入网页并窃取访问令牌。本地存储不提供Cookie在安全属性中具有的任何安全措施。不要误解我的意思,如果令牌存储在没有适当保护的Cookie中,那么我们也容易受到XSS攻击。但是Cookie具有保护令牌免受这些类型攻击的机制,这就是为什么OWASP社区也建议使用Cookie存储令牌。

丢效
如开头所述,令牌是自包含的。没有中央机构跟踪和管理令牌。当试图使令牌无效时,这成为一个挑战。默认情况下,访问令牌的生存期为1小时,到期的详细信息包含在令牌中。

未加密
请记住,令牌是签名的,但不是加密的。因此,如果不使用HTTPS进行充分保护,令牌内容可能会暴露给未经授权的各方。

 

posted @ 2024-07-23 16:34  carol2014  阅读(4)  评论(0编辑  收藏  举报