• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于java:Cookies的SameSite属性

java 搞代码 3年前 (2022-02-14) 53次浏览 已收录 0个评论

自Chrome 51版本开始,浏览器的 Cookies 新增了一个SameSite属性,用来避免 CSRF 攻打和信息透露,更多信息参考chrome Feature: ‘SameSite’ cookie attribute。

简略回顾什么是CSRF攻打

Cookies往往用来存储用户的身份信息,歹意网站通过设法伪造带有正确Cookies进行 HTTP 申请,这就是 CSRF 攻打。

举例来说,用户登陆了银行网站your-bank.com,银行服务器发来了一个 Cookie。

Set-Cookie: session_id=abc123;

用户起初又拜访了歹意网站malicious-site.com,歹意网站总是千方百计让你在歹意站点发送一个表单申请。

伎俩:中奖填写分割信息、通明的form表单提交按钮、附加在引诱图片上的超链接

<code class="html"><form action="your-bank.com/transfer" method="POST">
  ...
</form>

用户一旦被诱骗发送这个表单,银行网站就会收到带有正确 Cookie 的申请。为了避免CSRF攻打,银行网站表单会设置一个暗藏域,表单提交时一起带上一个随机token至服务器,通知服务器这是实在申请。

<code class="html"><form action="your-bank.com/transfer" method="POST">
  <input type="hidden" name="token" value="dad3weg34">
  ...
</form>

之所以被CSRF攻打,是因为歹意网站诱导你在其页面上发送了第三方cookie(此时的银行网站cookie为第三方cookie),它除了用于 CSRF 攻打,还能够用于用户追踪。

第三方是一种绝对概念,规定假设你正在拜访的站点为第一方站点,则浏览器为第二方,其余网站就是第三方站点,第三方站点诱导你发送第一方站点的cookie时,咱们就说此时的cookie为第三方cookie。

比方,Facebook 在第三方网站插入一张看不见的图片。

<code class="html"><img src="facebook.com" style="visibility:hidden;">

浏览器加载下面代码时,就会向 Facebook 收回带有 Cookie 的申请,从而 Facebook 就会晓得你是谁,拜访了什么网站。

SameSite

cookies机制始终被认为是不平安的,随着技术的更新,界内始终在欠缺cookies的平安机制,SameSite属性是谷歌浏览器为欠缺cookies平安机制出的个性之一。

Cookie 的SameSite属性用来限度第三方 Cookie的行为。

它能够设置三个值。

  • Strict
  • Lax
  • None

Strict

Strict最为严格,齐全禁止第三方 Cookie,当以后站点与申请指标站点是跨站关系时,总是不会发送 Cookie。换言之,只有以后站点 与申请指标站点是同站关系时,才会带上 Cookie。

Set-Cookie: CookieName=CookieValue; SameSite=Strict;

这个规定过于严格,可能造成十分不好的用户体验。

举例说明:

假设你以后所处站点地址为https://obmq.com/index.html,该站须要通过XHR申请获取某天气站点的将来7天的天气信息https://weather-forecast.org/api/weather?future=7,该接口要求必须携带cookieSet-Cookie: vip=true; Path=/; HttpOnly; SameSite=Strict;,这种状况下,你无论如何都无奈在https://obmq.com站点下发送这个XHR申请时还能携带上这个cookie,换句话说,你发送的接口申请的cookie申请头肯定不会有vip=true,即便你当初曾经是该天气网站的vip。

None

None在Chrome 85 版本之前是SameSite的默认设置值,即Set-Cookie: key=value; SameSite=None等于Set-Cookie: key=value

在Chrome 85 版本之前,显示设置SameSite=None不须要设置Secure属性,具体参见:Reject insecure SameSite=None cookies

在Chrome 85 版本当前,站点抉择显式敞开SameSite属性时,在将其值设为None的同时。必须同时设置Secure属性(示意Cookie 只能通过 HTTPS 协定发送),否则有效。

上面的设置无效。

Set-Cookie: widget_session=abc123; SameSite=None; Secure

上面的设置有效。

Set-Cookie: widget_session=abc123; SameSite=None

Lax

Chrome 在85版本后将Lax设为SameSite的默认值,即Set-Cookie: key=value; SameSite=Lax等于Set-Cookie: key=value,具体参见:Cookies default to SameSite=Lax。

Lax规定比拟宽松,大多数状况也不发送第三方 Cookie,然而导航到指标站点的 Get 申请除外。

Set-Cookie: CookieName=CookieValue; SameSite=Lax;

导航到指标站点的 GET 申请,只包含三种状况:链接,预加载申请,GET 表单。详见下表。

申请类型 示例 SameSite=None;Secure Lax
链接 <a href=”…”></a> 发送 Cookie 发送 Cookie
预加载 <link rel=”prerender” href=”…”/> 发送 Cookie 发送 Cookie
GET 表单 <form method=”GET” action=”…&来源gao@!dai!ma.com搞$$代^@码网#8221;> 发送 Cookie 发送 Cookie
POST 表单 <form method=”POST” action=”…”> 发送 Cookie 不发送
iframe <iframe src=”…”></iframe> 发送 Cookie 不发送
xhr/fetch $.get(“…”) 发送 Cookie 不发送
Image <img src=”…”> 发送 Cookie 不发送
Script <script src=”…”> 发送Cookie 不发送

设置了StrictLax当前,根本就杜绝了 CSRF 攻打。当然,前提是用户浏览器反对 SameSite 属性。

Schemeful Same-Site

自Chrome 86版本开始,思考到不平安的http://协定依然为网络攻击者提供了篡改cookie的机会,而后将这些cookie用于站点平安的https://。谷歌浏览器批改了cookie的Same Site的定义,将在雷同域名的平安(https://)协定和不平安(http:…跨站的判断因素之一。详情参见Feature: Schemeful same-site

如果您的站点全面降级到https协定,那么上面的内容不适宜您;如果您的站点是https协定和http协定混存,那么您须要关注。

常见的 “cross-scheme” Cookies携带状况

超链接

Schemeful Same-Site禁止时,从http:// site.example链接到https://site.example时,即便SameSite=Strict仍然会携带上cookie。

Schemeful Same-Site启用时,从http:// site.example链接到https://site.example时,SameSite=Strict的cookies会被锁定,其余cookies携带的体现如下图和下表:

<figcaption style=”text-align: center;”>Cross-scheme navigation from HTTP to HTTPS.</figcaption>

<br/>

HTTP → HTTPS HTTPS → HTTP
SameSite=Strict ⛔ Blocked ⛔ Blocked
SameSite=Lax ✓ Allowed ✓ Allowed
SameSite=None;Secure ✓ Allowed ⛔ Blocked
加载子资源

加载子资源的形式包含images, iframes, 和XHR or Fetch的网络申请。

加载子资源分为http加载https子资源https加载子http资源,携带cookies的体现如下图和下表:

Schemeful Same-Site禁止时,加载子资源时,SameSite=Strict 或者SameSite=Lax的cookie会被携带上。

Schemeful Same-Site启用时,加载子资源时,SameSite=Strict或者SameSite=Lax的cookies会被锁定,其余cookies携带的体现如下图和下表:

<figcaption style=”text-align: center;”>An HTTP page including a cross-scheme subresource via HTTPS.</figcaption>

<br/>

HTTP → HTTPS HTTPS → HTTP
SameSite=Strict ⛔ Blocked ⛔ Blocked
SameSite=Lax ⛔ Blocked ⛔ Blocked
SameSite=None;Secure ✓ Allowed ⛔ Blocked
POST 表单

Schemeful Same-Site禁止时,发送POST表单时,SameSite=Strict 或者SameSite=Lax的cookie会被携带上。

Schemeful Same-Site启用时,发送POST表单时,只有SameSite=None的cookies会被携带,其余cookies携带的体现如下图和下表:

<figcaption style=”text-align: center;”>Cross-scheme form submission from HTTP to HTTPS.</figcaption>

<br/>

HTTP → HTTPS HTTPS → HTTP
SameSite=Strict ⛔ Blocked ⛔ Blocked
SameSite=Lax ⛔ Blocked ⛔ Blocked
SameSite=None;Secure ✓ Allowed ⛔ Blocked
对WebSockets的影响?

如果WebSocket连贯与页面的安全性雷同,则仍将被视为同站。

https://连贯wss://被视为同站;http://连贯ws://被视为同站,否则视为跨站。具体如下:

Same-site:

  • wss://https:// 连贯
  • ws://http:// 连贯

Cross-site:

  • wss://http:// 连贯
  • ws://https:// 连贯

最佳实际

仍然应用token机制避免CSRF攻打

设置了SameSite属性值为StrictLax当前,根本杜绝了 CSRF 攻打。然而SameSite是Cookies属性之一,所以存在以下诸多限度:

  • 要求浏览器必须兼容Cookies的SameSite属性
  • 要求客户端利用必须反对Cookies机制,比方APP和微信小程序并不反对Cookies

限度如上所列,但不限于所列。

因为SameSite属性存在以上限度,所以须要服务器端仍然采纳token机制来避免CSRF攻打。

显示指定SameSite属性值为LaxStrict

总应该设置一个显式的SameSite属性,而不是依赖浏览器为您利用的默认设置。这使您对Cookie的应用用意更加明确,并进步了跨浏览器取得统一体验的机会。

不兼容的客户端的解决

对于SameSite属性的兼容性在不同浏览器和雷同浏览器的不同版本之间是不同的,能够参考chromium.org上的更新页面的已知的不兼容客户端以理解以后已知的问题,然而无奈确定是否详尽无遗。 只管这不是现实的抉择,但能够在此过渡阶段中采纳一些解决办法。

形式一:同时设置兼容SameSite属性的客户端和不兼容SameSite属性的客户端

// ~ 同时设置兼容SameSite属性的客户端和不兼容SameSite属性的客户端

// ~ 对于兼容SameSite属性的客户端,显示指定SameSite属性值以明确应用用意
Set-cookie: 3pcookie=value; SameSite=None; Secure

// ~ 对于不兼容SameSite属性的客户端,不设置SameSite属性
Set-cookie: 3pcookie-legacy=value; Secure

上面的示例显示了如何应用Express框架及其cookie-parser中间件在Node.js中执行此操作。

<code class="javascript">const express = require('express');
const cp = require('cookie-parser');
const app = express();
app.use(cp());

app.get('/set', (req, res) => {
  // Set the new style cookie
  res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true });
  // And set the same value in the legacy cookie
  res.cookie('3pcookie-legacy', 'value', { secure: true });
  res.end();
});

app.get('/', (req, res) => {
  let cookieVal = null;

  if (req.cookies['3pcookie']) {
    // check the new style cookie first
    cookieVal = req.cookies['3pcookie'];
  } else if (req.cookies['3pcookie-legacy']) {
    // otherwise fall back to the legacy cookie
    cookieVal = req.cookies['3pcookie-legacy'];
  }

  res.end();
});

app.listen(process.env.PORT);

形式二:判断客户端的user-agent

在发送Set-Cookie相应头时,您能够抉择通过user-agent字符串检测客户端。请参阅不兼容客户端的列表,建议您找一个工具库来解决user-agent,因为您很可能不想本人编写这些正则表达式。

这种办法的益处在于,它只须要在设置cookie时进行一次更改即可。 然而,此处必须指出是user-agent嗅探自身是不牢靠的,并且可能无奈捕捉所有受影响的用户。

无论抉择哪种形式,倡议确保有一种记录低版本客户端比例的办法。 一旦比例降落到网站可承受的阈值以下,请确保您有揭示或警报以删除此代替办法。

谷歌打算推出”Privacy Sandbox”

谷歌打算齐全禁止第三方cookie,毕竟cookie真的不是很平安,具体参考this

参考链接

  • SameSite cookies explained
  • SameSite cookies recipes
  • Schemeful Same-Site
  • Cookie 的 SameSite 属性 – 阮一峰的网络日志

文章同步公布在各大支流常识共享平台,所以设github为对立的反馈区

疑难、探讨、问题反馈:https://github.com/weixsun/di…

关注微信公众号 obmq 及时理解最新动静


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于java:Cookies的SameSite属性

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址