【问题标题】:Post from another domain causes session null来自另一个域的帖子导致会话空
【发布时间】:2020-02-07 21:58:52
【问题描述】:

我们有一个这样的支付子系统;

  • 用户输入支付数据
  • 付款数据发送到第 3 方服务 url(带有表单 post / 例如。POST https://3rdparty.com/form
  • 第三方服务检查数据并发送一些其他数据(再次使用表单发布,但这次发送到我们的 url / 例如 POST http://localhost/Success

换句话说;

http://localhost/Page1 -> POST https://3rdparty.com/Service -> POST http://localhost/Success

但是当第二次重定向(第三方服务向我们这边发布数据)时,会话对象变为空。

我已经从同源其他源模拟了POST场景到http://localhost/Success

同源发帖时

http://localhost/Test -> POST -> http://localhost/Success  => OK. Session IS NOT null

但是当从另一个来源发帖时

http://testdomain/Test -> POST -> http://localhost/Success  => OK. Session IS null

顺便说一句;无论其他来源的协议如何,无论是 http 还是 https

,都会发生这种情况

这种行为的根源是什么?我找不到任何有意义的东西...

编辑:

我添加了 ActionFilterAttribute 的代码,它拦截每个请求并检查会话(由于 @mxmissile 的评论)

public class LoginFilter : System.Web.Mvc.ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Session[Constants.SessionNames.USER_OBJECT_NAME] == null) 
// this is where I check the Session object and it's null
// it doesn't have any key in it
            {
                filterContext.HttpContext.Session.Abandon();
                filterContext.Result = new RedirectResult("/Login/Login");

            }

        }
    }

编辑 2:

使用下面的配置,它重写了 Set-Cookie 标头的标志,我能够修改标志。 (建议https://blog.elmah.io/the-ultimate-guide-to-secure-cookies-with-web-config-in-net);

<rewrite>
    <outboundRules>
      <clear />
      <rule name="Add SameSite" preCondition="No SameSite">
        <match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
        <action type="Rewrite" value="{R:0}; SameSite=lax" />
      </rule>
      <preConditions>
        <preCondition name="No SameSite">
          <add input="{RESPONSE_Set_Cookie}" pattern="." />
          <add input="{RESPONSE_Set_Cookie}" pattern="; SameSite=lax" negate="true" />
        </preCondition>
      </preConditions>
    </outboundRules>
  </rewrite>

但由于 Chrome 的 80.x 更新,SameSite=Lax 没有将 cookie 发送到此处 https://www.thinktecture.com/identity/samesite/prepare-your-identityserver/ 所述的第 3 方服务

所以我将SameSite=lax 更改为SameSite=none 并且它起作用了

但正如我想象的那样,这会产生新的安全问题。比如CSRF攻击。

最好的方法是什么?

【问题讨论】:

  • 有一个用于 asp.net 会话跟踪的 cookie,其中包含会话标识符。在浏览器中检查这个 asp.net 会话 cookie 标志SameSite,它是设置为 LAX 还是 Strict? LAX 意味着只有使用 GET 执行跨站点请求时,cookie 才会发送到服务器。严格意味着它永远不会通过跨站点请求发送到服务器。
  • 您如何以及在何处确定 Session 为空?
  • @lgor 我如何检查标志SameSite。我已经在此页面下方应用了规则 blog.elmah.io/… ,但它没有用。 @mxmissile 我在 Success 控制器上有一个 ActionFilterAttribute。其中ActionExecutingContext.HttpContext.Session 为空
  • 发布您的过滤器属性代码。
  • 我已经发布了。

标签: c# .net asp.net-mvc


【解决方案1】:

我假设您已经使用 SameSite=None; Secure 并指出一些可能有用的东西。

这种行为的根源是什么?

Chromuim SameSiteFAQ page 很好地总结了变化是什么:

问:SameSite 有哪些新变化?

Chrome 正在更改在第一方和第三方上下文中发送 cookie 的默认行为。

正如我想象的那样,这会产生新的安全问题。

根据我对上面引用的解释,我不这么认为:Chrome 现在默认会发送 less cookie。通过恢复发送这些 cookie,您并没有增加攻击面——您只是恢复了现有的流量。 实际上,如果您进一步阅读该页面,现在需要做一件事 - 通过HTTPS 发送 cookie。因此,您实际上最好承认这些 cookie 很敏感并要求用户始终选择安全连接这一事实。

如 CSRF 攻击。

我不认为这一点取决于 Chrome Cookie 政策。它仍然有效。如果还没有这样做,请查看Microsoft docsumentation,看看标准的 Razor Html 助手是否适合您:

@using (Html.BeginForm("Login", "Login")) {
    @Html.AntiForgeryToken()
}

最好的方法是什么?

看看 Google 如何将其作为默认行为进行推广,恐怕最好的办法就是采用它。

【讨论】:

    猜你喜欢
    • 2018-09-16
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    相关资源
    最近更新 更多