跳到主要内容

认识

2024年04月08日
柏拉文
越努力,越幸运

一、认识


Cookie 最开始被设计出来其实并不是来做本地存储的,而是为了弥补HTTP在状态管理上的不足。HTTP 协议是一个无状态协议,客户端向服务器发请求,服务器返回响应,故事就这样结束了,但是下次发请求如何让服务端知道客户端是谁呢?这种背景下,就产生了 Cookie.

Cookie 本质上就是浏览器里面存储的一个很小的文本文件,内部以键值对的方式来存储(在chrome开发者面板的Application这一栏可以看到)。向同一个域名下发送请求,都会携带相同的 Cookie,服务器拿到 Cookie 进行解析,便能拿到客户端的状态。

Cookie Cookie 的体积上限只有4KB,只能用来存储少量的信息。Cookie 紧跟域名,不管域名下面的某一个地址需不需要这个 Cookie ,请求都会携带上完整的 Cookie,这样随着请求数的增多,其实会造成巨大的性能浪费的,因为请求携带了很多不必要的内容。由于 Cookie 以纯文本的形式在浏览器和服务器中传递,很容易被非法用户截获,然后进行一系列的篡改,在 Cookie 的有效期内重新发送给服务器,这是相当危险的。另外,在HttpOnlyfalse 的情况下,Cookie 信息能直接通过 JS 脚本来读取。

二、安全属性


2.1 secure

secure: 标记为SecureCookie只能通过被HTTPS协议加密过的请求发送给服务端,可以借此来预防中间人攻击

2.2 httpOnly

httpOnly 设置后,只能通过 HTTP 响应报文的 Set-Cookie 来新增或更新 cookie ,客户端无法通过脚本的方式来读写 cookie。对于敏感信息比如用户凭证,请一定要加上 HttpOnly。如果攻击者成功地实施了 XSS 攻击,会因为无法读取 cookie 而拿不到敏感信息。JavaScriptDocument.cookie无法访问带有HttpOnly属性的Cookie

Set-Cookie: token=abcd; HttpOnly

2.3 samesite

samesite: 性允许服务器要求某个Cookie在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击。也就是说 samesite 用来标明这个 Cookie 是个同站 Cookie,同站Cookie只能作为第一方Cookie,不能作为第三方Cookie

Cookie与域关联。如果此域与您所在页面的域相同,则该Cookie称为第一方Cookiefirst-party cookie)。如果域不同,则它是第三方Cookiethirty-patry cookie)。第三方Cookie是由第三方网站引导发出的,可以用于CSRF攻击以及用户行为追踪。

可选值:

  • samesite=none: 会携带 cookie。但前提是 Secure 设置为 true,即只能在 HTTPS 协议下使用(之前的标准没有这个要求)。

  • samesite=strict: 只在访问相同站点时发送Cookie, 完全禁止第三方获取cookie, 跨站点时,任何情况下都不会发送cookie。这种称为严格模式,表明这个 Cookie 在任何情况下都不可能作为第三方 Cookie,绝无例外。但是跳转子域名或者是新标签重新打开刚登陆的网站,之前的Cookie都不会存在。尤其是有登录的网站,那么我们新打开一个标签进入,或者跳转到子域名的网站,都需要重新登录。对于用户来讲,可能体验不会很好。

  • samesite=lax: 防范跨站,大多数情况下禁止获取cookie,除非导航到目标网址的GET请求(链接预加载GET表单)。这种称为宽松模式,比 Strict 放宽了点限制。假如这个请求是这种请求(改变了当前页面或者打开了新页面)且同时是个GET请求,则这个Cookie可以作为第三方Cookie。如果SamesiteCookie被设置为Lax,那么其他网站通过页面跳转过来的时候可以使用Cookie,可以保障外域连接打开页面时用户的登录状态。但相应的,其安全性也比较低。在 Chrome 80 版本之后,CookieSameSite 由原来的 None 改为了 Lax

注意: 大多数网站已经将SameSite的默认值设置为Lax,此时如果网站想要关闭SameSite属性,必须在将SameSite属性设置为None的同时设置Secure属性,否则无效。

// 该设置无效
Set-Cookie: widget_session=abc123; SameSite=None

// 有效设置
Set-Cookie: widget_session=abc123; SameSite=None; Secure

三、作用域属性

3.1 domain

domain: 为cookie设置域名,如果请求域名与该字段匹配,那么就继续检查path字段。

Domain=.mozilla.org

3.2 path

path: 如果域名匹配,那么会检查path匹配情况,如果也匹配,请求中就会带上cookie

3.3 expires

expires 表示 cookie 的过期时间点,使用了 GMT 时间格式的字符串。通过设置 max-age 或者 expires 删除 cookie

Set-Cookie: token=abcd; Expires=Fri, 29 Apr 2022 05:29:01 GMT

3.4 max-age

max-Age 表示 cookie 的有效时间长度,单位为秒。通过设置小于等于 0 的数字,可以让一个 cookie 失效。如果 Max-AgeExpires 同时存在,以 Max-Age 为准。通过设置 max-age 或者 expires 删除 cookie

Set-Cookie: token=abcd; Max-Age=6000