Skip to content

Set cookies the right way

Published on: December 22, 2023    Categories: Django, Python, Security

This is part of a series of posts I’m doing as a sort of Python/Django Advent calendar, offering a small tip or piece of information each day from the first Sunday of Advent through Christmas Eve. See the first post for an introduction.

Cookies in the cookie jar

Django’s request and response objects, and their attributes and methods, make dealing with cookies easy. You can read from the request.COOKIES dictionary to get a cookie, and you can use the response’s set_cookie() method to set cookies. What else do you need?

Well, potentially a few things.

First of all, it’s worth reviewing those arguments to set_cookie(), because several of them are important. You should probably always set:

You should also strongly consider setting httponly=True when possible; this will instruct the browser not to let JavaScript access that cookie (though it will still be sent normally with requests). The Django settings SESSION_COOKIE_HTTPONLY and CSRF_COOKIE_HTTPONLY control this for the session and CSRF cookies; the session cookie defaults to True, while the CSRF cookie defaults to False (since, as the documentation points out, if an attacker can already run JavaScript that would access that cookie, you’re busted anyway).

Django also supports using signed cookies as a tamper-proofing mechanism. To set a signed cookie, use the set_signed_cookie() method, and to read it, use the get_signed_cookie() method (instead of directly accessing request.COOKIES). You should also look into providing the salt argument, which acts as an additional input to the signing algorithm to help partition different usages of Django’s signing utilities (which by default use the value of your SECRET_KEY setting as the signing key; specifying the salt will combine the salt value and the SECRET_KEY to produce a unique signing key. This prevents use of signing tools in one part of a site from acting as an oracle for signing on another part of the same site.

Just be careful about trying to do too much with signed cookies. Signing only gives you a check against tampering, and doesn’t encrypt or otherwise usefully obscure the value stored in the cookie, and browsers tend to have a limit (usually 4KB) on how much data they can store in a single cookie, so trying to put large amounts of data in a signed cookie isn’t a great idea.