Ticket #3304: httponly.patch

File httponly.patch, 3.8 KB (added by cephelo@…, 8 years ago)

patch for supporting HttpOnly in cookies/session

  • conf/global_settings.py

     
    264264SESSION_COOKIE_SECURE = False             # Whether the session cookie should be secure (https:// only).
    265265SESSION_SAVE_EVERY_REQUEST = False        # Whether to save the session data on every request.
    266266SESSION_EXPIRE_AT_BROWSER_CLOSE = False   # Whether sessions expire when a user closes his browser.
     267SESSION_HTTP_ONLY = False                 # Whether to use the non-RFC standard httpOnly flag (IE, FF3+, others)
    267268
    268269#########
    269270# CACHE #
  • contrib/sessions/middleware.py

     
    9494                    datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE))
    9595                response.set_cookie(settings.SESSION_COOKIE_NAME, session_key,
    9696                    max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
    97                     secure=settings.SESSION_COOKIE_SECURE or None)
     97                    secure=settings.SESSION_COOKIE_SECURE or None,
     98                    httponly=settings.SESSION_HTTP_ONLY or None)
    9899        return response
  • http/__init__.py

     
    11import os
    2 from Cookie import SimpleCookie
     2from Cookie import SimpleCookie, Morsel
    33from pprint import pformat
    44from urllib import urlencode, quote
    55from django.utils.datastructures import MultiValueDict
     
    153153        cookiedict[key] = c.get(key).value
    154154    return cookiedict
    155155
     156class MorselWrapper(Morsel):
     157    " Identical to Cookie.Moresel but intercepts httponly-aware "
     158    def __setitem__(self, K, V):
     159        K = K.lower()
     160        if K == "httponly":
     161            if V:
     162                self.__dict__.__setitem__(K, "")
     163        else:
     164            super(MorselWrapper, self).__setitem__(K, V)
     165
     166    def OutputString(self, attrs=None):
     167        output = super(MorselWrapper, self).OutputString(attrs)
     168        if "httponly" in self.__dict__:
     169            output += "; httpOnly"
     170        return output
     171
     172class SimpleCookieWrapper(SimpleCookie):
     173    " Identical to Cookie.SimpleCookie but intercepts cookie creation to use MorselWrapper "
     174    def __set(self, key, real_value, coded_value):
     175        M = self.get(key, MorselWrapper())
     176        M.set(key, real_value, coded_value)
     177        dict.__setitem__(self, key, M)
     178
     179    def __setitem__(self, key, value):
     180        rval, cval = self.value_encode(value)
     181        self.__set(key, rval, cval)
     182
    156183class HttpResponse(object):
    157184    "A basic HTTP response, with content and dictionary-accessed headers"
    158185    def __init__(self, content='', mimetype=None):
     
    167194            self._container = [content]
    168195            self._is_string = True
    169196        self.headers = {'Content-Type': mimetype}
    170         self.cookies = SimpleCookie()
     197        self.cookies = SimpleCookieWrapper()
    171198        self.status_code = 200
    172199
    173200    def __str__(self):
     
    196223                return True
    197224        return False
    198225
    199     def set_cookie(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=None):
     226    def set_cookie(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=None):
    200227        self.cookies[key] = value
    201         for var in ('max_age', 'path', 'domain', 'secure', 'expires'):
     228        for var in ('max_age', 'path', 'domain', 'secure', 'expires', 'httponly'):
    202229            val = locals()[var]
    203230            if val is not None:
    204231                self.cookies[key][var.replace('_', '-')] = val
Back to Top