Missing cookies when using ASGI and HTTP/2

[BUG] Missing csrftoken cookie when using granian over HTTP/2 · Issue #9935 · paperless-ngx/paperless-ngx · GitHub describes the issue in more detail. In a nutshell: when serving a Django app using ASGI and HTTP/2, cookies may get dropped. In case this hits the csrftoken cookie, it might explain the various “CSRF verification failed” topics in this forum category.

I had a brief look at the coke and it looks like the ASGI module joins multiple values for the same header using commas but parse_cookie splits by semicolon.

Same same issue has also hit other ASGI frameworks: Separate cookie headers are not parsed into `Request.cookies` under HTTP/2 · encode/starlette · Discussion #2916 · GitHub

I’m not familiar with Django, so it would be great if someone could fact-check the above.

And because new users can only include two links in a post, here are the code pointers:

ASGI module: django/django/core/handlers/asgi.py at main · django/django · GitHub

parse_cookie: django/django/http/cookie.py at main · django/django · GitHub

Hi @IngmarStein, thanks for opening the discussion.

Yes, ASGIRequest needs to special case handling the cookie header here, in a similar way as it does with content-length &co.

Here’s a minimal reproduce:

from django.conf import settings
from django.core.handlers.asgi import ASGIRequest

settings.configure(DEBUG=True)

scope = {
    "type": "http",
    "asgi": {
        "version": "3.0",
        "spec_version": "2.3",
    },
    "http_version": "2.0",
    "method": "GET",
    "scheme": "http",
    "path": "/",
    "raw_path": b"/",
    "query_string": b"",
    "root_path": "",
    "headers": [
        (b"cookie", b"a=abc;"),
        (b"cookie", b"b=def;"),
        (b"cookie", b"c=ghi;")
    ],
    "client": ("127.0.0.1", 10000),
    "server": ("127.0.0.1", 8000),
    "extensions": {}
}

request = ASGIRequest(scope, None)

print(request.COOKIES)  # Prints: {'a': 'abc', ',b': 'def', ',c': 'ghi'}
assert request.COOKIES == {'a': 'abc', 'b': 'def', 'c': 'ghi'}

Would you care to create a ticket on the issue tracker? https://code.djangoproject.com
You can link back here if you like?

1 Like

Thanks for the confirmation and the repro! I’ve created #36399 (Missing cookies when using ASGI and HTTP/2) – Django to track this. The special case seems easy enough.

1 Like