HttpOnly with Django
Did you ever wonder what the dirtiest way to add HttpOnly cookies to Django was, without having to patch both Django and Python?
Well, through the amazing flexibility of the Python language, and the black art of monkeypatching, here’s how:
from Cookie import Morsel
from django.http import HttpResponse
def http_only_cookie(fn):
def wrap(self, key, *args, **kwargs):
fn(self, key, *args, **kwargs)
self.cookies[key]['HTTPOnly'] = True
return wrap
def exclude(fn, field):
fields = fn()
for idx, (k, v) in enumerate(fields):
if field == k:
fields.pop(idx)
return fields
def append_httponly(fn):
def wrap(self, *args, **kwargs):
out = fn(self, *args, **kwargs)
return out+'; HttpOnly'
return wrap
def bootstrap_httponly():
HttpResponse.set_cookie = http_only_cookie(HttpResponse.set_cookie)
Morsel._reserved['httponly'] = 'httponly'
Morsel.items = lambda self: exclude(super(Morsel, self).items, 'httponly')
Morsel.OutputString = append_httponly(Morsel.OutputString)
Now just stick this in one of your __init__.py files:
from myapp.httponly import bootstrap_httponly bootstrap_httponly()
And enjoy cookies like:
Set-Cookie: sessionid=weirdhash; Domain=.foo.org; expires=Fri, 18-Sep-2009 13:18:52 GMT; Max-Age=1209600; Path=/; HttpOnly
And that’s that.
