JayBee has asked for the wisdom of the Perl Monks concerning the following question:

Looks like there's change coming soon regarding cookies requiring "SameSite" to be defined, as I get a warning when I inspect (browser developer mode)

Cookie “CGISESSID” does not have a proper “SameSite” attribute value. Soon, cookies without the “SameSite” attribute or with an invalid value will be treated as “Lax”. This means that the cookie will no longer be sent in third-party contexts. If your application depends on this cookie being available in such contexts, please add the “SameSite=None“ attribute to it. To know more about the “SameSite“ attribute, read https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite

Below is my test attempt to force "samesite" and "secured" values. This test sets the cookie, but my hash inserts do not take according to the browser Cookie manager plugin. Any thoughts on a better work around? Trying to stick with CGI::Session as it's server-side storage, though CGI::Cookie may have to be my next route.

use strict; use CGI ':standard'; use CGI::Carp 'fatalsToBrowser'; use CGI::Session; use Data::Dumper; my $CS=new CGI::Session(); $CS->expire('+1d'); $CS->{_QUERY}->{'.cookies'}->{CGISESSID}->{samesite}='Lax'; $CS->{_QUERY}->{'.cookies'}->{CGISESSID}->{secure}=1; print $CS->header(); print start_html('Test'); print Dumper($CS->{_QUERY}->{'.cookies'}->{CGISESSID}); print end_html;

(Edit: add-on) While testing further and trying CGI::Cookie, I'm still not able to assign "SameSite" values, but I am able to set others (secure, httponly)

my $cookie=CGI::Cookie->new( -name=>$CS->name, -value=>$CS->id, -samesite=>'Lax', # (Lax, Strict, None) tested unsuccessfully -secure=>1, -httponly=>1 ); print header(-cookie=>$cookie);

Replies are listed 'Best First'.
Re: CGI::Session Cookies
by haukex (Archbishop) on Jul 09, 2022 at 08:40 UTC

    Note that CGI::Session was last released in 2011, its maintainer hasn't made any CPAN releases since 2012, it has 23 open issues on RT, and its maintainer hasn't made any commits to the repo since 2015 and it is now marked read-only. In general, CGI.pm, while it still works, isn't really recommended any more, and especially not for new developments. In particular, you're using its HTML generation functions, which are deprecated (I'm printing strings below, which isn't recommended either, but since this is about cookies and the strings are entirely static, I think it's ok for this demo).

    For more modern approaches, see e.g. this node, in particular I personally like Mojolicious, which supports (client-side) sessions out of the box, and I have quite a few examples on my scratchpad, for example a comparison between Mojo and CGI.pm here.

    Soon, cookies without the “SameSite” attribute or with an invalid value will be treated as “Lax”.

    Note that this means that explicitly setting the value to "Lax" doesn't seem strictly necessary, other than perhaps to quiet the warning.

    Anyway, one way that I see that this issue could be patched is by subclassing CGI::Session and overriding its cookie method, which is what generates the cookies (this is called by its header method, which is why your approach to reaching into the query object didn't work). Though CGI::Cookie doesn't document it, which I am guessing may be an oversight instead of an intentional omission, it does have accessors to change its samesite etc. properties.

    use warnings; use strict; use CGI; use CGI::Carp 'fatalsToBrowser'; use CGI::Session; package CGI::Session::Mine { use parent 'CGI::Session'; sub cookie { my $self = shift; my $cookie = $self->SUPER::cookie(@_); $cookie->secure(1); $cookie->samesite('Lax'); return $cookie; } } my $CS = CGI::Session::Mine->new(); $CS->expire('+1d'); print $CS->header(); print '<!DOCTYPE html><html><head><title>Test</title></head>' .'<body><h1>Test</h1></body></html>';

    An alternative is to patch directly into CGI::Session using Class::Method::Modifiers, since the former's cookie method does support the passing of additional parameters to the constructor:

    use warnings; use strict; use CGI; use CGI::Carp 'fatalsToBrowser'; use CGI::Session; use Class::Method::Modifiers 'around'; around 'CGI::Session::cookie' => sub { my ($orig, $self) = (shift, shift); $orig->($self, @_, secure=>1, samesite=>'Lax'); }; my $CS = CGI::Session->new(); $CS->expire('+1d'); print $CS->header(); print '<!DOCTYPE html><html><head><title>Test</title></head>' .'<body><h1>Test</h1></body></html>';

    In fact, you can mix and match the two approaches of patching the method vs. subclassing, and modifying the returned cookie vs. passing additional arguments to the method.

    While testing further and trying CGI::Cookie, I'm still not able to assign "SameSite" values

    This workaround works for me, perhaps your version of CGI::Cookie is too old?

      Interesting new ways to write html not using CGI.. I will have to review Mojo and re-learn perl after this project. Apparently old-school approach has a count-down timer, esp with tech.

      UPDATE: Used your 'Subclassing' sript... Brilliant! :D
      Thank you.

      Even added httponly, as js will never use this.

      $cookie->secure(1); $cookie->samesite('Strict'); $cookie->httponly(1);
Re: CGI::Session Cookies
by Your Mother (Archbishop) on Jul 09, 2022 at 14:35 UTC

    Make sure you have the right version of CGI::Cookie. SameSite support was added in 2016 and has been mentioned in the changelog a couple of times since.

    >perl -MCGI::Cookie -E'say CGI::Cookie->new(-name=>"a",-value=>"b",-sa +mesite=>"Lax")' a=b; path=/; SameSite=Lax >cpanm CGI::Cookie CGI::Cookie is up to date. (4.54)
      Yes, updating CGI::Cookie had the proper effect and was able to get the correct output with my 2nd approach. Thank you