30

ASP.NET Core Cookie SameSite

 3 years ago
source link: http://beckjin.com/2020/09/12/aspnet-cookie-samesite/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在较多的项目中,Cookie 是比较常用的一种状态保持的选择。比如常见的例子:用户登录成功后,服务器通过 set-cookie 将会话Id设置到当前域下,前端在调用后端接口时,会自动将同域下的 Cookie 携带上,然后后端接口再获取到会话Id进行用户登录状态的合法性验证。

了解过 Cookie 相关知识的同学都比较清楚,Cookie 的使用上一不小心就会出现安全性问题,如:CSRF(Cross-site request forgery 跨站请求伪造)、XSSI(Cross Site Script Inclusion 跨站脚本包含)攻击,网上也有很多这一类的介绍文章。为了降低这类风险,谷歌开发了一种称为 Cookie SameSite 安全机制,并已经在主流的浏览器中被应用较长时间。

什么是 Cookie SameSite

SameSite 是 Cookie 中的一个属性,它是用来约束第三方( 跨域 ) Cookie 传递的,SameSite 有 StrictLaxNone 三个值可设置。

Strict

Strict 是最严格的策略,在 Strict 下,浏览器不允许将 Cookie 从 A 域发送到B域。假设用户之前在 B 域下已经是登录状态,A 域某页面上有一个 B 域的跳转链接,当通过点击 A 域下这个跳转链接进入 B 域时,B 域下会出现未登录的情况。这种策略的安全性很高,但其实在用户体验上并不好,所以使用上并不常见。

set-cookie: sid=0920770230c103809305605a;samesite=strict

Lax

Lax 策略相比 Strict 会宽一些,大多数情况也是不发送第三方 Cookie,但 链接(<a href="..."></a>)预加载请求 <link rel="prerender" href="..."/>GET 表单 <form method="GET" action="..."> 除外。假设用户之前在 B 域下已经是登录状态,A 域某页面上有一个 B 域的链接,当通过点击 A 域下这个跳转链接进入 B 域时,B 域下将依然显示登录状态。但如果在 A 域下发起了一个 Ajax POST 请求到 B 域的接口,这时接口是获取不到相关 Cookie 的。虽然 Lax 策略依然会存在一定的风险,但通常来说是相对合适的选择,所以 Lax 在一些开发语言中被设置为 Cookie SameSite 的默认值。

set-cookie: sid=0920770230c103809305605a;samesite=lax

None

在实际使用中,也会存在有一些场景确实是需要支持跨域 Cookie 传递( 如比较常见的 A 域中 IFrame 嵌入 B 域链接进行使用 ),这时候可以选择将 SameSite 设置为 None,但是使用 None 却是有前提条件的,它要求必须同时设置 Secure 属性为 true,而 Secure 设置 true 又要求 B 域是基于 HTTPS 协议来访问的,否则依然无效。

set-cookie: sid=0920770230c103809305605a; secure; samesite=none

在 .NET Core 中的使用

下面将以 ASP.NET Core Web 应用程序为例

var options = new CookieOptions
{
  Expires = DateTime.Now.AddHours(1),
};
_httpContextAccessor.HttpContext.Response.Cookies.Append("sid", "0920770230c103809305605a", options);

常规情况下,以上代码即可完成 Cookie 的写入,CookieOptions 还支持一些其他的配置,可根据实际情况设定。不过需要注意的是在 .NET Core 2.2 和 .NET Core 3.1 中,Cookie 的 SameSite 属性默认值是不也一样的,升级需要注意。

2.2 中的默认值是 SameSiteMode.Lax

e6VrIvQ.png!mobile

3.1 中的默认值变成了 SameSiteMode.Unspecified (表示不写入 SameSite 属性值,继承浏览器默认的 Cookie 策略)

3MjAreq.png!mobile

IFrame 中如何解决 SameSite 问题

在基于 ASP.NET Core set-cookie 的情况下,如果需要当前域被其他域的 IFrame 引入使用,最基本的要求是站点必须基于 HTTPS 协议,然后修改代码将 SameSite 属性值设置为 None,Secure 设置为 true。

var options = new CookieOptions
{
    SameSite = SameSiteMode.None,
    Secure = true
};

yqiQvm.png!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK