Application Integration
If you are using the werkzeug request objects you could integrate the secure cookie into your application like this:
from werkzeug.utils import cached_property
from werkzeug.wrappers import BaseRequest
from werkzeug.contrib.securecookie import SecureCookie
# don't use this key but a different one; you could just use
# os.urandom(20) to get something random
SECRET_KEY = '\xfa\xdd\xb8z\xae\xe0}4\x8b\xea'
class Request(BaseRequest):
@cached_property
def client_session(self):
data = self.cookies.get('session_data')
if not data:
return SecureCookie(secret_key=SECRET_KEY)
return SecureCookie.unserialize(data, SECRET_KEY)
def application(environ, start_response):
request = Request(environ)
# get a response object here
response = ...
if request.client_session.should_save:
session_data = request.client_session.serialize()
response.set_cookie('session_data', session_data,
httponly=True)
return response(environ, start_response)
A less verbose integration can be achieved by using shorthand methods:
class Request(BaseRequest):
@cached_property
def client_session(self):
return SecureCookie.load_cookie(self, secret_key=COOKIE_SECRET)
def application(environ, start_response):
request = Request(environ)
# get a response object here
response = ...
request.client_session.save_cookie(response)
return response(environ, start_response)
- 2014 by the Werkzeug Team, see AUTHORS for more details.
Security
The default implementation uses Pickle as this is the only module that used to be available in the standard library when this module was created. If you have simplejson available it’s strongly recommended to create a subclass and replace the serialization method:
import json
from werkzeug.contrib.securecookie import SecureCookie
class JSONSecureCookie(SecureCookie):
serialization_method = json
The weakness of Pickle is that if someone gains access to the secret key the attacker can not only modify the session but also execute arbitrary code on the server.
Reference
class werkzeug.contrib.securecookie.SecureCookie(data=None, secret_key=None, new=True)
Represents a secure cookie. You can subclass this class and provide an alternative mac method. The import thing is that the mac method is a function with a similar interface to the hashlib. Required methods are update() and digest().
Example usage:
[UNKNOWN NODE doctest_block]- data – the initial data. Either a dict, list of tuples or [UNKNOWN NODE title_reference].
- secret_key – the secret key. If not set [UNKNOWN NODE title_reference] or not specified
it has to be set before
serialize()
is called. - new – The initial value of the [UNKNOWN NODE title_reference] flag.
new
[UNKNOWN NODE title_reference] if the cookie was newly created, otherwise [UNKNOWN NODE title_reference]
modified
Whenever an item on the cookie is set, this attribute is set to [UNKNOWN NODE title_reference]. However this does not track modifications inside mutable objects in the cookie:
[UNKNOWN NODE doctest_block]In that situation it has to be set to [UNKNOWN NODE title_reference] by hand so that
should_save
can pick it up.
static hash_method()
The hash method to use. This has to be a module with a new function or a function that creates a hashlib object. Such as [UNKNOWN NODE title_reference] Subclasses can override this attribute. The default hash is sha1. Make sure to wrap this in staticmethod() if you store an arbitrary function there such as hashlib.sha1 which might be implemented as a function.
classmethod load_cookie(request, key='session', secret_key=None)
Loads a SecureCookie
from a cookie in request. If the
cookie is not set, a new SecureCookie
instanced is
returned.
- request – a request object that has a [UNKNOWN NODE title_reference] attribute which is a dict of all cookie values.
- key – the name of the cookie.
- secret_key – the secret key used to unquote the cookie. Always provide the value even though it has no default!
classmethod quote(value)
Quote the value for the cookie. This can be any object supported
by serialization_method
.
quote_base64 = True
if the contents should be base64 quoted. This can be disabled if the serialization process returns cookie safe strings only.
save_cookie(response, key='session', expires=None, session_expires=None, max_age=None, path='/', domain=None, secure=None, httponly=False, force=False)
Saves the SecureCookie in a cookie on response object. All
parameters that are not described here are forwarded directly
to set_cookie()
.
- response – a response object that has a
set_cookie()
method. - key – the name of the cookie.
- session_expires – the expiration date of the secure cookie stored information. If this is not provided the cookie [UNKNOWN NODE title_reference] date is used instead.
serialization_method = <module 'pickle' from '/usr/lib/python2.7/pickle.pyc'>
the module used for serialization. Unless overriden by subclasses the standard pickle module is used.
serialize(expires=None)
Serialize the secure cookie into a string.
If expires is provided, the session will be automatically invalidated after expiration when you unseralize it. This provides better protection against session cookie theft.
datetime.datetime
object)should_save
True if the session should be saved. By default this is only true
for modified
cookies, not new
.
classmethod unquote(value)
Unquote the value for the cookie. If unquoting does not work a
UnquoteError
is raised.
classmethod unserialize(string, secret_key)
Load the secure cookie from a serialized string.
- string – the cookie value to unserialize.
- secret_key – the secret key used to serialize the cookie.
SecureCookie
.exception werkzeug.contrib.securecookie.UnquoteError
Internal exception used to signal failures on quoting.