使用相同站点cookie属性防止CSRF

时间:2016-08-15 12:10:18

标签: asp.net iis cookies csrf

我在网上冲浪并找到文章Preventing CSRF with the same-site cookie attribute

在链接维护时我们需要添加Set-Cookie标头。

  

Set-Cookie:key = value;仅Http; SameSite =严格

现在我的问题是,我想在我的ASP.NET站点中的所有Cookie和身份验证Cookie中设置它。 我尝试使用来自IIS的标头来设置它,但有人说这是错误的实现方式。

我也在下面尝试过。

HttpCookie newAuthenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName
                    , FormsAuthentication.Encrypt(newAuthenticationTicket))
                {
                    HttpOnly = true
                };
newAuthenticationCookie.Values.Add("SameSite", "strict");

但似乎没有帮助我。

请建议我更好的方法。

感谢。

8 个答案:

答案 0 :(得分:22)

HttpCookie Source进行深入审核后,确认我们无法使用代码执行此操作,因为无法在Cookie上添加额外属性,并且类被标记为已密封。

  

但无论如何我仍然通过修改 web.config 来管理解决方案。

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

在每个 Set-Cookie 上添加 SameSite =严格

答案 1 :(得分:10)

只需添加我的答案即可系统化此处和其他位置找到的所有信息。

1。为了保护4.7.2及更高版本下的自定义Cookie

var c = new HttpCookie("test");
c.SameSite = SameSiteMode.Lax;

2。保护表单身份验证Cookie

在web.config中

<authentication mode="Forms">
    <forms ..... cookieSameSite="Lax" />
</authentication>

3。保护ASP.NET会话Cookie

在Global.asax中

void Session_Start(Object sender, EventArgs e)
{
    Response.Cookies["ASP.NET_SessionId"].SameSite = SameSiteMode.Lax;
    //while we're at it lets also make it secure
    if (Request.IsSecureConnection)
        Response.Cookies["ASP.NET_SessionId"].Secure = true;
}

有趣的事实:即使您设置了<httpCookies requireSSL="true" />,ASP.NET会话cookie 出于某种原因仍将是不安全的

4。 <httpCookies samesite=xxx>不存在

像以上在web.config中的注释中所建议的那样添加<httpCookies sameSite="Strict" />无效,我遇到了错误。

  

无法识别的属性“ samesite”

即使我的目标是4.7.2。在多个项目和多台机器上进行了测试,VS2019也不在intellisense中显示此信息,MS文档也没有在任何地方提及它。

答案 2 :(得分:7)

您还可以在创建Cookie时在代码中设置此内容:

var httpCookie = new HttpCookie("mycookie", "myvalue");
httpCookie.Path += ";SameSite=Strict";

Response.SetCookie(httpCookie);

这将为您提供以下标题:

Set-Cookie:mycookie=myvalue; path=/;SameSite=Strict
在它被推入框架之前,它是一个黑客攻击。

答案 3 :(得分:6)

为了将SameSite定义为ASP.NET_SessionId cookie,我必须在system.web部分下设置web.config:

<sessionState cookieSameSite="Lax" />

答案 4 :(得分:5)

因为在这个时代,我们使用owin修复同样愚蠢的webapi cookie bug ...

public class CookieSameSiteMiddleware : OwinMiddleware
{
    public CookieSameSiteMiddleware(OwinMiddleware next) : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        var url = context.Request.Path.Value.ToLowerInvariant();

        if (url.Contains("/api/mylogin"))
        {
            context.Response.OnSendingHeaders(x =>
            {
                var scv = context.Response.Headers.FirstOrDefault(h => h.Key == "Set-Cookie");
                if (!scv.Equals(default(KeyValuePair<string, string[]>)))
                {
                    //context.Response.Headers.Remove("Set-Cookie");
                    context.Response.Headers.Set("Set-Cookie", scv.Value[0] + "; SameSite=strict");
                }

            }, null);
        }

        await this.Next.Invoke(context);
    }
}

确保在.UseWebApi()

之前注册了中间件

答案 5 :(得分:5)

.NET 4.7.2现已内置支持SameSite属性。 HttpClass现在有一个名为SameSite的属性。查看来自Microsoft的更多信息here

不再需要通过配置文件来破解它。

答案 6 :(得分:0)

在4.7.2之前的版本中,您只需将字符串附加到Cookie路径即可。

FormsAuthentication.SetAuthCookie(username, false, FormsAuthentication.FormsCookiePath + "; SameSite=Lax");

答案 7 :(得分:0)

https://www.nuget.org/packages/Microsoft.Owin.Security.Cookies/4.1.0现在支持SameSite。

这是一个好消息,因为此处的其他解决方案效果不佳:

实施OwinMiddleware :除了性能外,效果很好。这可能是特定于我们的环境的,但是该解决方案大约占我们CPU的10%。

<outboundRules>:大概有可能开始工作。但是,到目前为止,我见过的所有我们测试过的解决方案(包括该线程中的一个)在将多个Cookie设置在同一响应中时都存在一些问题。