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.
var c = new HttpCookie("test"); c.SameSite = SameSiteMode.Lax;
In web.config
<authentication mode="Forms"> <forms ..... cookieSameSite="Lax" /> </authentication>
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.
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