Django

Code

Ticket #3304: httponly.patch

File httponly.patch, 3.8 kB (added by cephelo@gmail.com, 1 year ago)

patch for supporting HttpOnly? in cookies/session

  • conf/global_settings.py

    old new  
    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

    old new  
    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

    old new  
    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