Preventing CSRF with the same-site cookie attribute

I was surfing the web and found article Preventing CSRF with the same-site cookie attribute.

As on link maintain We need to add Set-Cookie header.

Set-Cookie: key=value; HttpOnly; SameSite=strict

Now My Question is, I want to set this in my ASP.NET site in all Cookies and Authentication Cookie.
I tried to set this using header from IIS but someone says this is wrong way implementation.

I have also tried below.

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

But it seems like not helping me.

Please suggest me a better way to do this.

Thanks.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

After Deep review on HttpCookie Source it’s confirm that we cannot do this with the code, as there is no way to add extra attribute on Cookie and class is marked as sealed.

But still anyhow I manage solution by modifying web.config as below.

<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>

This add SameSite=strict on each Set-Cookie.

Method 2

You can also set this in code when creating a cookie:

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

Response.SetCookie(httpCookie);

This will give you the following header:
Set-Cookie:mycookie=myvalue; path=/;SameSite=Strict

bit of a hack until it’s pushed in to the framework.

Method 3

Just adding my answer to systematize all the info found here and in other places.

1. To secure custom cookies under 4.7.2 and later

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

2. To secure Forms authentication cookie

In web.config

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

3. To secure ASP.NET Session cookie

In 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;
}

Fun fact: even if you set <httpCookies requireSSL="true" /> the ASP.NET session cookie will still be non-secure for some reason.

3(a). UPDATE 01.2020: .NET 4.8 Session cookie is now “SameSite” by default

Installing the latest Windows Update will make your session cookies Lax by default. You can control it here:

<sessionState cookieSameSite="Lax" /> <!-- in system.web -->

4. <httpCookies samesite=xxx> does not exist?

Adding <httpCookies sameSite="Strict" /> like suggested in the comment above in web.config didn’t work, I was getting the error.

Unrecognized attribute ‘samesite’

Even though I’m targeting 4.7.2. Tested on multiple project and multiple machines, also VS2019 does not show this in intellisense and MS docs do not mention it anywhere.

Method 4

.NET 4.7.2 has now built-in support for SameSite property.
The HttpCookie has now a property called SameSite.
See more info here from Microsoft.

No need anymore to hack this through the config file.

Method 5

In order to have SameSite defined to ASP.NET_SessionId cookie I had to set the web.config under system.web section:

<sessionState cookieSameSite="Lax" />

Method 6

Because in this day and age we use owin to fix the same silly 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);
    }
}

Make sure the middle-ware is registered before .UseWebApi()

Method 7

Pre 4.7.2 you can just append the string to the cookie path.

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

Method 8

https://www.nuget.org/packages/Microsoft.Owin.Security.Cookies/4.1.0 now supports SameSite.

That is very good news because the other solutions here doesn’t work that brilliantly:

Implementing OwinMiddleware: Works great, except for performance. This might be something specific for our environment but that solution was about 10% of our CPU.

<outboundRules>: Probably possible to get working. But all solutions I’ve seen so far and we tested, including the one in this thread, had some issues when multiple cookies where set in the same response.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x