0

I have an existing web application using Python Twisted. The clients are embedded devices rather than humans. So I occasionally run into quirks of the often outdated and simplistic http clients in these devices. The application relies on session cookies, up until now I've had no issues.

Recently I have added a new type of device and I am having problems with session matching not working.

I am using getSession() from the twisted.web.server Session class.

This particular client device seems to be returning the Cookie header in a format that getSession is unable to match to a session (and so creates a new session on every request received).

I am unsure if this is a problem with Twisted or a problem with how the client device is formatting the cookie header, specifically how it's reformatting the Path attribute.

The behaviour of a working client device is this.

The Set-Cookie header being sent by Twisted:

Set-Cookie: TWISTED_SESSION=10d4ed8a01ad1459c53018953343f2d357e9ac5015a86ab714fd09eb12b06c4c; Path=/

And the resulting Cookie header sent by the client on the next request:

Cookie: $Version="0"; TWISTED_SESSION=10d4ed8a01ad1459c53018953343f2d357e9ac5015a86ab714fd09eb12b06c4c;$Path=/

Now the non-working client, the Set-Cookie header from the Twisted web server:

Set-Cookie: TWISTED_SESSION=fe5abac62eb577176e94d2a98d46298d6c093d425e51583554a4ad98e3cff8fb; Path=/

And the resulting Cookie header that Twisted Session does not match:

Cookie: TWISTED_SESSION=fe5abac62eb577176e94d2a98d46298d6c093d425e51583554a4ad98e3cff8fb/

It's just put the path "/" onto the end of the TWISTED_SESSION attribute.

I'm a bit stuck on how to diagnose this further, I've attempted to re-write the Cookie header and remove the / from the end but this didn't help.

I am also unsure whether the client's behaviour should be correct or not. It seems unusual but I don't know if what it is doing is technically wrong.

Paul Hayes
  • 31
  • 1

1 Answers1

0

I've figured a work-around for this out. I want to post it here just in case it's useful to anyone else.

In short the actual answer is that the HTTP client is broken and sending the Cookie header incorrectly.

I'm happy for someone to prove otherwise but from my own reading of RFC6265 & the Mozilla developer documentation there's no allowance for appending the Path attribute onto the end of another cookie (name=value) pair. Given that the pair names are arbitrary it wouldn't make any sense.

I added a monkeypatch to work-around this problem. It's messy but it allows me to test this device further is of some use:

from twisted.web.http import Request
def parseCookies(self):
    """                                                                                                                                     
    Parse cookie headers.                                                                                                                   

    This method is not intended for users.                                                                                                  
    """
    cookieheaders = self.requestHeaders.getRawHeaders(b"cookie")

    if cookieheaders is None:
    return

    for cookietxt in cookieheaders:
        if cookietxt:
            for cook in cookietxt.split(b';'):
        cook = cook.lstrip()
                try:
                    k, v = cook.split(b'=', 1)
                    self.received_cookies[k] = v.split(b'/')[0]
                except ValueError:
                    pass

Request.parseCookies = parseCookies
Paul Hayes
  • 31
  • 1