Secure Cookie

2018-02-24 15:39 更新

Secure Cookie

This module implements a cookie that is not alterable from the clientbecause it adds a checksum the server checks for. You can use it assession replacement if all you have is a user id or something to marka logged in user.

Keep in mind that the data is still readable from the client as anormal cookie is. However you don't have to store and flush thesessions you have at the server.

Example usage:

>>> from werkzeug.contrib.securecookie import SecureCookie
>>> x = SecureCookie({"foo": 42, "baz": (1, 2, 3)}, "deadbeef")

Dumping into a string so that one can store it in a cookie:

>>> value = x.serialize()

Loading from that string again:

>>> x = SecureCookie.unserialize(value, "deadbeef")
>>> x["baz"]
(1, 2, 3)

If someone modifies the cookie and the checksum is wrong the unserializemethod will fail silently and return a new empty SecureCookie object.

Keep in mind that the values will be visible in the cookie so do notstore data in a cookie you don't want the user to see.

Application Integration

If you are using the werkzeug request objects you could integrate thesecure 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, start_response)

    # 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, start_response)

    # get a response object here
    response = ...

    request.client_session.save_cookie(response)
    return response(environ, start_response)

Security

The default implementation uses Pickle as this is the only module thatused to be available in the standard library when this module was created.If you have simplejson available it's strongly recommended to create asubclass 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 keythe attacker can not only modify the session but also execute arbitrarycode 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 providean alternative mac method. The import thing is that the mac methodis a function with a similar interface to the hashlib. Requiredmethods are update() and digest().

Example usage:

>>> x = SecureCookie({"foo": 42, "baz": (1, 2, 3)}, "deadbeef")
>>> x["foo"]
42
>>> x["baz"]
(1, 2, 3)
>>> x["blafasel"] = 23
>>> x.should_save
True
参数:
  • data – the initial data. Either a dict, list of tuples or None.
  • secret_key – the secret key. If not set None or not specifiedit has to be set before serialize() is called.
  • new – The initial value of the new flag.

new
True if the cookie was newly created, otherwise False

modified
Whenever an item on the cookie is set, this attribute is set to True.However this does not track modifications inside mutable objectsin the cookie:

>>> c = SecureCookie()
>>> c["foo"] = [1, 2, 3]
>>> c.modified
True
>>> c.modified = False
>>> c["foo"].append(4)
>>> c.modified
False

In that situation it has to be set to modified by hand so thatshould_save can pick it up.

hash_method()
The hash method to use. This has to be a module with a new functionor a function that creates a hashlib object. Such as hashlib.md5Subclasses can override this attribute. The default hash is sha1.Make sure to wrap this in staticmethod() if you store an arbitraryfunction there such as hashlib.sha1 which might be implementedas a function.

classmethod load_cookie(request, key='session', secret_key=None)
Loads a SecureCookie from a cookie in request. If thecookie is not set, a new SecureCookie instanced isreturned.

参数:
  • request – a request object that has a cookies attributewhich 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 hasno default!

classmethod quote(value)
Quote the value for the cookie. This can be any object supportedby serialization_method.

quote_base64 = True
if the contents should be base64 quoted. This can be disabled if theserialization 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. Allparameters that are not described here are forwarded directlyto set_cookie().

参数:
  • response – a response object that has aset_cookie() method.
  • key – the name of the cookie.
  • session_expires – the expiration date of the secure cookiestored information. If this is not providedthe cookie expires date is used instead.

serialization_method = <module 'pickle' from '/usr/lib/python2.7/pickle.pyc'>
the module used for serialization. Unless overriden by subclassesthe standard pickle module is used.

serialize(expires=None)
Serialize the secure cookie into a string.

If expires is provided, the session will be automatically invalidatedafter expiration when you unseralize it. This provides betterprotection against session cookie theft.

should_save
True if the session should be saved. By default this is only truefor modified cookies, not new.

classmethod unquote(value)
Unquote the value for the cookie. If unquoting does not work aUnquoteError 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.
返回:

a new SecureCookie.

exception werkzeug.contrib.securecookie.UnquoteError
Internal exception used to signal failures on quoting.

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号