ServiceStack with .Net Framework SameSite Error

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.

Yep that’s the correct API which has been deprecated & renamed in later versions.

Hi Mythz

I know this thread is one year old but I think it’s the best place where to write, the topic is exactly the same

I’m on net 4.8, selfhostedapp, SS 5.9.2

I’m using your code snippet to remove SameSite from session cookies

I know it’s not advisable, my target is to simplify frontend developers life, not production

I find the SetCookieFilter seems to work for only one cookie at a call

when browser open the app my code is called more times
when I inspect the response’s headers sent to the browser I see the ss-id cookie is set in the first call then the ss-pid cookie is set in then next call and so on

if I remove the overridden method I see the two cookies setted in the response to the first call

I simplify the code as follow, behaviour unchanged

        if (!base.SetCookieFilter(req, cookie))
            return false;

        var cookieStr = cookie.AsHeaderValue();

        req.Response.AddHeader("Set-Cookie", cookieStr);
        return false; 

I cannot figure out why this behaviour but it happens also in credentials call causing the backend session never go to authenticated

Any advice?

SetCookieFilter() gets called for each cookie that’s created, you can check which cookie it’s being called for with cookie.Name, e.g:

public override bool SetCookieFilter(IRequest req, Cookie cookie)
{
    if (cookie.Name == "...") { .. }
    return base.SetCookieFilter(req, cookie);
}

If you’re using SS v5.9.2 it should set SameSite=None if you configure it to with:

SetConfig(new HostConfig {
    UseSameSiteCookies = false,
});

I don’t understand the other behavior you’re describing that it still creates cookies, are you saying if you clear your cookies and always return false that it still creates cookies?

public override bool SetCookieFilter(IRequest req, Cookie cookie) => false;

this is the method

    public override bool SetCookieFilter(IRequest req, Cookie cookie)
    {
        var cookieStr = cookie.AsHeaderValue();
        req.Response.AddHeader("Set-Cookie", cookieStr);
        return false;
    }

then start the app, open the browser and point to http://localhost
the cookies ss-id and ss-pid are not set in the same call


then I clear the browser cache, cookies, data…
and remove the method completely and redo the same ops
now I see both cookies set in the first call

the same happens with credentials call if SetCookieFilter method is there

the issue is that credentials call is one and I expect the app sets all the cookies in the response otherwise next browser call sends some old cookies of unauthorized session

Was the ss-pid cookie sent in the Request Header? It only creates session cookies that don’t exist, there’s a good chance the permanent session id (ss-pid) already existed, whilst temporary ss-id session cookie wont for a new browser session.

Also what’s causing the redirect on the home page?

browser cache, data… all clear before each try

the redirect is ordered by the backend when the client points to the root /

you can see the redirect also in last screen where SetCookieFilter is not present and the cookies work as expected

HttpListener’s AddHeader() could be setting/overriding the header instead of adding it, try adding it to the headers collection directly:

public override bool SetCookieFilter(IRequest req, Cookie cookie)
{
    var cookieStr = cookie.AsHeaderValue();
    req.Response.Headers.Add(HttpHeaders.SetCookie, cookieStr);
    return false;
}

Also is overriding SetCookieFilter() now required when SameSite cookies is disabled?

SetConfig(new HostConfig {
    UseSameSiteCookies = false,
});