ServiceStack with .Net Framework SameSite Error

Hi,

We are using ServiceStack v5.0 with Asp.Net Framework and currently seeing this error when running angular Apps that communicate with ServiceStack APIs in Chrome:

A cookie associated with a cross-site resource at was set without the SameSite attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with SameSite=None and Secure

Could you please advise what we need to add to the APIs to set these two cookie options?

Thanks,
Leeny

You’ll need to set the new HttpCookie.SameSite property which requires upgrading to .NET Framework v4.7.2, you can set by overriding HttpCookieFilter in your AppHost, e.g:

public override void HttpCookieFilter(HttpCookie cookie)
{
    cookie.SameSite = SameSiteMode.None;
}

Thanks Demis. Is there any option available without upgrading ServiceStack as we are couple of days from a release?

Do you have this HttpCookieFilter on your AppHost?

You should also be able to specify it in your Web.config, e,g:

<configuration>
 <system.web>
  <httpCookies sameSite="None" requireSSL="true" />
 <system.web>
<configuration>

Note: Cookies that assert SameSite=None must also be marked as Secure.

Thanks Demis. I did try adding the HttpCookieFilter but i could not see the option for SameSiteMode. I believe we are using ServiceStack package v5.1.0. Should HttpCookieFilter be available in this version?

Should I be adding this to the class below:

public class MyApiHost : AppHostBase

Or as a configuration setting under SetConfig  with other settings?

SetConfig(new HostConfig()
{ … }

If not, I will try the web.config setting.

Thanks a lot,
Leeny

Are you on .NET Framework v4.7.2 or later? You need to be.

Oh ok, Thanks, we are on .Net Framework 4.6 for these APIs. I will try the web.config setting for now until we get a chance to upgrade.

Please read the MS docs, this is a new feature added in v4.7.2 you need to upgrade to .NET Framework v4.7.2 or over.

Ok, got it now. thnks for your help again.

Sorry, one more question:
Is there a way to add the SameSite attribute to the cookies manually using a Response filter or something like that?

Thanks,
Leeny

As mentioned above you can set it in HttpCookieFilter()

But you still need to be on at least .NET Framework v4.7.2, the HttpCookie.SameSite property you need to set literally doesn’t exist before then.

Hi, I am just looking at options without upgrading .Net Framework (if that’s even possible) - something like retrieving response Set-Cookie headers and adding the SameSite and Secure attributes?

Note in the latest v5.8.1 on MyGet it will use reflection to set the SameSite cookie in .NET v4.7.2+ from ServiceStack’s net45 builds.

One thing you can try is override ASP.NET’s Cookie APIs which isn’t advisable but may work, you can try overriding SetCookieFilter() in your AppHost and basically return false everytime to prevent ServiceStack from using ASP.NET’s Cookie APIs to set it, then try set it manually, something like:

public override bool SetCookieFilter(IRequest req, Cookie cookie)
{
    if (!base.SetCookieFilter(req, cookie))
        return false;
    
    var cookieStr = cookie.AsHeaderValue();
    if (cookieStr.IndexOf("SameSite=", StringComparison.OrdinalIgnoreCase) < 0)
    {
        cookieStr += ";SameSite="+(Config.UseSameSiteCookies ? "Strict":"None");
    }
    req.Response.AddHeader("Set-Cookie", cookieStr);            

    return false;
}

But it’s a hack I wouldn’t recommend using, upgrade .NET Framework to v4.7.2 instead. Also note to send None SameSite cookies you need to be over a secure connection (https) and you need to use Secure Cookies, i.e:

SetConfig(new HostConfig {
    UseSecureCookies = true,
});
1 Like

Hi Demis,

I am planning on doing some tests upgrading to .Net Framework v4.7.2. Quick question, are SetCookieFilter and HttpCookieFilters methods available with Service Stack v5.1.0 nuget package?

I am unable to see these two methods.

Thanks,
Leeny

No but you can use the older named AllowSetCookie() API which was renamed to SetCookieFilter().

Thanks Demis.

public override bool AllowSetCookie(IRequest req, string cookieName)

Is the best to retrieve the cookie based on the cookie name from the request.Response object and then set SameSite mode and Secure properties there?

It’s best to update to update to .NET Framework v4.7.2+ so you can use the official APIs, .NET Framework upgrades are generally very stable & backwards-compatible so that’d always be my first option. Failing that I’d personally use the hack posted in my comment above.

Thanks Demis. I have upgraded to v4.7.2 now and then set up web.config as per MS docs. I can now see ss-id and ss-pid with secure as true and sameSite as none. However, ss-opt cookie is returned as secure = false.

Is there anything specific I need to use for this one?

As a side, if I need to resort to code changes to do this, what would be the preferred options:

  1. ASP.Net response filter to manually force all cookies to set secure and sameSite attributes?, or
  2. ServiceStack global response filter to update response cookies to set secure and sameSite attributes?, or
  3. I haven’t tried using AllowSetcookie yet - but how do you recommend getting the cookie by name inside AllowSetCookie?

Thanks a lot,
Leeny

Are you using a SSL (https) connection? and did you specify to use Secure Cookies?

AllowSetCookie gets called with the cookie name, you don’t have access to the cookie in the old AllowSetCookie API.

SameSite now gets populated in v5.8.1. so if you upgrade to v5.8.1 you’d just need to configure to use SameSite & Secure Cookies, e.g:

SetConfig(new HostConfig {
    UseSameSiteCookies = true,
    UseSecureCookies = true,
})

Prior to v5.8.1 but with access to the HttpCookieFilter you could set it there.

Otherwise if you’ve updated to v4.7.2 you should be able to specify it in your Web.config.

1 Like

Thanks Demis. My version of ServiceStack does not have UseSecureCookies, I only have ‘OnlySendSessionCookiesSecurely’ which I have set to true. And yes, I can confirm that this is over https.