Remove specific cookie with Nginx


Remove specific cookie with Nginx

2017/03/27

Tags: nginx cookie

Snippet

This snippet should remove some_cookie cookie from the request before passing it to the backend:

set $new_cookie $http_cookie;

if ($http_cookie ~ "(.*)(?:^|;)\s*some_cookie=[^;]+(.*)") {
    set $new_cookie $1$2;
}
proxy_set_header Cookie $new_cookie;

This is somewhat the complete configuration I use:

server {

    [...]
    set $new_cookie $http_cookie;

    if ($http_cookie ~ "(.*)(?:^|;)\s*some_cookie=[^;]+(.*)") {
        set $new_cookie $1$2;
    }
    proxy_set_header Cookie $new_cookie;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;

        if (!-f $request_filename) {
            proxy_pass http://backend;
            break;
        }
    }
}

Context

I was using Django 1.9 and suddenly started getting CSRF validation errors out of nowhere. The way CSRF validation works in Django is that the request should have a csrftoken cookie and submitted form should have a hidden field with the same CSRF cookie as value. In my case, both were true and I was still getting CSRF errors. Django was complaining about the missing CSRF cookie. I was puzzled at first. CSRF cookie was being sent out by the browser piggybacked in the request but somehow it was not ending up in Django. Turned out the cookie parsing logic in 1.9 was failing because one of the third-party cookies was a JSON-like. It caused the parser to skip cookies after this cookie. I had to remove this cookie before the request is passed to Django. This was a temporary solution. The better way was to upgrade Django.

References

https://forum.nginx.org/read.php?2,252944,252947#msg-252947