如何在使用 SameSite=Strict 的 OAUTH2 之后重定向并仍然获取我的 cookie?

Gar*_*idd 25 cookies google-chrome oauth-2.0

日!继40781534 之后,接受的答案是设置SameSite=Lax

即使用户的请求本身是从我的 OAUTH2 提供程序上的登录页面SameSite=Strict重定向,我该如何设置重定向到自己的 cookie,以便我可以从 Chrome 取回 cookie 56.0.2924.87

完整的请求链是:

  • POST https://provider.com/callback? 302 FOUND和:

    Location: https://me/login?code=xxx&state=yyy
    
    Run Code Online (Sandbox Code Playgroud)
  • GET https://example.com/login?code=xxx&state=yyy? 302 FOUND303 SEE OTHER(似乎无关紧要)与:

    Location: https://example.com/destination
    Set-Cookie: sid=zzzz; Secure; HttpOnly; SameSite=Strict; Path=/
    
    Run Code Online (Sandbox Code Playgroud)
  • GET https://example.com/destination? 401 GET OFF MY LAWN因为浏览器没有显示sidcookie

  • GET https://example.com/destination? 200 OK如果我刷新,因为网站是相同的,我的浏览器会显示sidcookie

我欣赏提出的CSRF潜力sid,以/destination不被用户的最后一次加载页面的一般情况example.com,但我只是刚刚设置/login,而我是一个现在重定向到/destination

当然,我可以设置SameSite=Lax,但是如果有人可以找到某种方法通过错误形成 URL 来触发他们从我的网站选择的重定向,那么是否会有一些点击劫持的可能性?

Ala*_*zek 14

我认为出于安全原因不能这样做。 SameSite=Strict意味着如果用户已被重定向或只是点击了指向您网站的链接(来自其他主机),则不应发送 cookie。重定向就像“链接”请求。因此,如果您的服务器重定向到另一个服务器并且该服务器立即使用 3xx 代码重定向回来,则将发送 cookie,因为您的服务器位于该链的“顶部”。

但是,如果您重定向到 oauth 提供商并且用户必须允许您访问他的帐户,则意味着此“链”已损坏,即使您的站点设置了 cookie,也将不再发送 cookie(已设置但未发送)。您的重定向只是点击的“允许”链接的“扩展”。

如果您想防止其他人点击劫持您的网站,如果您认为必须防止这种行为,请在链接中使用 nonce,否则可能会很危险。但请考虑大多数提供商都在为您检查您的应用程序是否先前定义并允许了重定向 url。

这是其他解决方案(仅当您知道自己在做什么并且可以对自己承担 100% 责任时才使用)。

  • 使用“继续到站点”链接准备站点(当然会在点击链接后发送 cookie)
  • 使用 JavaScript 重新加载窗口
  • 使用 JavaScript 准备站点,这将重定向用户
  • 结合第一种和第三种方法以获得更清晰的解决方案,并且在浏览器中无需 JavaScript 支持即可工作。

我在开发时使用了第二个,现在我使用的是同一个站点松懈(这是 Hapi 中的默认设置,最多可能是 15 版,所以还不错)。

  • 另一种可能的解决方案:在 OAuth 流程开始时将会话令牌设置为“SameSite: Lax”,然后在 OAuth 回调中将其升级为“SameSite: Strict”。如果跨源请求还没有会话,则其造成的损害是有限的。 (3认同)

Geo*_*kos 7

带有 HTML 重定向的HTTP OK可确保重定向的请求实际发送SameSite=Strictcookie。

解决方法很简单。使用以下正文发送 200,而不是 302:

<html>
<head>
<meta http-equiv="refresh" content="0;URL='https://example.com/destination'"/>
</head>
<body><p>Moved to <a href="https://example.com/destination">https://example.com/destination</a>.</p></body>
</html>
Run Code Online (Sandbox Code Playgroud)

使用元刷新创建即时客户端重定向

我的 OIDC 场景涉及:

  • GET 302 https://strict 重定向到不同的域
  • GET 302 https://oidc 重定向
  • GET 200 https://oidc/2 好的
  • POST 302 http://strict
  • GET 200 https://strict/redirect?returnUrl=target(新的 HTML 重定向
  • GET 200 https://strict/target

通常我们会将 302 重定向到 OIDC POST 上的目标,但是,这不适用于SameSite=Strict. 浏览器拒绝发送 cookie,即使它存储了它。如果您关闭浏览器并重新打开,它将发送 cookie。通过添加额外的 HTML 重定向,浏览器会在请求最终 URL 时发送 cookie。

在 .NET Core 中,我可以通过将 替换Response.Redirect为 HTML 重定向解决方案来使用 SameSite=Strict cookie :

public sealed class OpenIdConnectHtmlRedirectHandler : OpenIdConnectHandler
{
    public OpenIdConnectHtmlRedirectHandler(IOptionsMonitor<OpenIdConnectOptions> options,
                                            ILoggerFactory logger,
                                            HtmlEncoder htmlEncoder,
                                            UrlEncoder encoder,
                                            ISystemClock clock) : base(options, logger, htmlEncoder, encoder, clock) { }

    public override async Task<bool> HandleRequestAsync()
    {
        if (!await base.HandleRequestAsync())
            return false;

        var headers = Response.GetTypedHeaders();
        if (null == headers.Location)
            return true;

        Response.ContentType = "text/html";
        Response.StatusCode = 200;
        headers.Location = null;
        await Response.WriteAsync($"<html><head><meta http-equiv=\"refresh\" content=\"0; URL='{location}'\"/></head></html>",
                                  Encoding.UTF8, Context.RequestAborted);
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)