7

In webapp2 documentation there is no mention of setting the SameSite attribute for a cookie, it seems to be built on the response handler from WebOB, I checked webOB doc page it clearly shows the 'SameSite' flag as an accepted cookie parameter

I tried to set it nonetheless in set cookie:

self.response.set_cookie(name, secure_cookie, path='/', secure=True,
httponly=True, samesite='lax', expires=expireDate)

But I received the below error:

TypeError: set_cookie() got an unexpected keyword argument 'samesite'

I know one can use self.response.headers.add_header('Set-Cookie', ... but I was hoping I could use self.response.set_cookie following the webapp2 documentation

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
Khaled
  • 907
  • 1
  • 8
  • 18

2 Answers2

4

Samesite was introduced in webob 1.8 but The App Engine Standard Environment SDK ships with 1.1.1 and 1.2.3 as built-in libraries.

You could try vendoring in a more recent webob to see if this overrides the built-in version.

Once a version of webob that supports samesite is installed, a samesite keyword argument can be passed to Response.set_cookie

class MyHandler(webapp2.RequestHandler):
    def get(self):
        self.response.set_cookie('cookie-name', value='42', samesite='lax')

This sample app sets samesite=strict on the session cookie generated by webapp2_extras.sessions, assuming the underlying webob package supports it.

import webapp2
from webapp2_extras import sessions


class HelloHandler(webapp2.RequestHandler):
    def dispatch(self):
        self.session_store = sessions.get_store(request=self.request)
        try:
            super(HelloHandler, self).dispatch()
        finally:
            self.session_store.save_sessions(self.response)

    @webapp2.cached_property
    def session(self):
        return self.session_store.get_session()

    def get(self):
        self.session['hello'] = 'world'
        self.response.headers['content-type'] = 'text/plain'
        self.response.write('Hello world')


webapp2_config = { 
    'webapp2_extras.sessions': {
        'secret_key': 's3cr3t',
        'cookie_args':{'samesite': 'strict'}
    },  
}

application = webapp2.WSGIApplication([
    webapp2.Route(r'/', handler=HelloHandler),
],
    config=webapp2_config)

The response's set-cookie header is

session=eyJoZWxsbyI6IndvcmxkIn0=|1595151290|09b22484901689e6eb0411792c8732ef134d2b66; Path=/; SameSite=strict
snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
  • 1
    That's sad :(! I don't think it's worth importing an underlying library for a missing flag, sounds like something GAE should have done, but I guess with their future plans to move to Python3 and the availability of other frameworks like Flask & Django they might stop upgrading webapp2 and its libraries. Thank you for the heads up! I will go with the add_header approach then.. – Khaled Apr 06 '19 at 12:50
  • 2
    @Khaled Please can you elaborate the add_header approach? How would you set the SameSite attribute on the cookie? – Yahya Jan 24 '20 at 17:23
  • if your project in running in django version>2.1 this will be fixed automatically if the version is not you have to implement that and had to set the headers using the middleware.[link](https://docs.djangoproject.com/en/3.0/ref/settings/#session-cookie-samesite) – i_am_deesh Jan 29 '20 at 19:25
  • @snakecharmerb any suggestions on how to make webapp2 use newer version of webob? I tired just importing it from vendor libs but no luck. I'm using webapp2.extras sessions, which uses set_cookie, so the workaround using add_header is quite tricky to get right. – Rob Curtis Jul 18 '20 at 08:10
  • @RobCurtis Are you using python2 or python3? – snakecharmerb Jul 18 '20 at 08:12
  • @snakecharmerb currently python2, haven't done that upgrade yet for gae. – Rob Curtis Jul 18 '20 at 10:17
  • @RobCurtis I've added an example to the answer. – snakecharmerb Jul 19 '20 at 09:56
  • @snakecharmerb thanks for this. The issue I have now is that webob doesn't support that (because it's the old version). So I assume I need to vendor in new version of webapp2 with latest webob? – Rob Curtis Jul 19 '20 at 10:08
  • 2
    I ran the example with webapp2 v2.5.2 in app.yaml.libraries and with the latest webob vendored in. (there's no need to specify webob in app.yaml in this case) – snakecharmerb Jul 19 '20 at 10:21
  • @Yahya - I added this type of solution here – Israel Oct 13 '20 at 14:36
1

I cracked this issue with header change, without install any external library. just use this function after set a cookie:

def AddSameSiteToCookies(self):
    for index, header in enumerate(self.response.headers._items):
        if header[0] == "Set-Cookie" and "SameSite" not in header[1]:
            temp = list(header)
            temp[1] = temp[1].replace("Path=", "SameSite=Lax; Path=")
            self.response.headers._items[index] = tuple(temp)
Israel
  • 1,165
  • 11
  • 11