Secure Cookie

最后更新于:2022-04-01 04:07:59

# 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 ~~~ <table class="docutils field-list" frame="void" rules="none"><col class="field-name"/><col class="field-body"/><tbody valign="top"><tr class="field-odd field"><th class="field-name">参数:</th><td class="field-body"><ul class="first last simple"><li><strong>data</strong> – the initial data. Either a dict, list of tuples or <cite>None</cite>.</li><li><strong>secret_key</strong> – the secret key. If not set <cite>None</cite> or not specifiedit has to be set before <a class="reference internal" href="#werkzeug.contrib.securecookie.SecureCookie.serialize" title="werkzeug.contrib.securecookie.SecureCookie.serialize"><tt class="xref py py-meth docutils literal"><span class="pre">serialize()</span></tt></a> is called.</li><li><strong>new</strong> – The initial value of the <cite>new</cite> flag.</li></ul></td></tr></tbody></table> 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 that[should_save](# "werkzeug.contrib.securecookie.SecureCookie.should_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](# "werkzeug.contrib.securecookie.SecureCookie") from a cookie in request. If thecookie is not set, a new [SecureCookie](# "werkzeug.contrib.securecookie.SecureCookie") instanced isreturned. <table class="docutils field-list" frame="void" rules="none"><col class="field-name"/><col class="field-body"/><tbody valign="top"><tr class="field-odd field"><th class="field-name">参数:</th><td class="field-body"><ul class="first last simple"><li><strong>request</strong> – a request object that has a <cite>cookies</cite> attributewhich is a dict of all cookie values.</li><li><strong>key</strong> – the name of the cookie.</li><li><strong>secret_key</strong> – the secret key used to unquote the cookie.Always provide the value even though it hasno default!</li></ul></td></tr></tbody></table> *classmethod *quote(*value*) Quote the value for the cookie. This can be any object supportedby [serialization_method](# "werkzeug.contrib.securecookie.SecureCookie.serialization_method"). | 参数: | **value** – the value to quote. | |-----|-----| 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(). <table class="docutils field-list" frame="void" rules="none"><col class="field-name"/><col class="field-body"/><tbody valign="top"><tr class="field-odd field"><th class="field-name">参数:</th><td class="field-body"><ul class="first last simple"><li><strong>response</strong> – a response object that has a<tt class="xref py py-meth docutils literal"><span class="pre">set_cookie()</span></tt> method.</li><li><strong>key</strong> – the name of the cookie.</li><li><strong>session_expires</strong> – the expiration date of the secure cookiestored information. If this is not providedthe cookie <cite>expires</cite> date is used instead.</li></ul></td></tr></tbody></table> 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. | 参数: | **expires** – an optional expiration date for the cookie (a[datetime.datetime](http://docs.python.org/dev/library/datetime.html#datetime.datetime "(在 Python v3.5)") [http://docs.python.org/dev/library/datetime.html#datetime.datetime] object) | |-----|-----| should_save True if the session should be saved. By default this is only truefor [modified](# "werkzeug.contrib.securecookie.SecureCookie.modified") cookies, not [new](# "werkzeug.contrib.securecookie.SecureCookie.new"). *classmethod *unquote(*value*) Unquote the value for the cookie. If unquoting does not work a[UnquoteError](# "werkzeug.contrib.securecookie.UnquoteError") is raised. | 参数: | **value** – the value to unquote. | |-----|-----| *classmethod *unserialize(*string*, *secret_key*) Load the secure cookie from a serialized string. <table class="docutils field-list" frame="void" rules="none"><col class="field-name"/><col class="field-body"/><tbody valign="top"><tr class="field-odd field"><th class="field-name">参数:</th><td class="field-body"><ul class="first simple"><li><strong>string</strong> – the cookie value to unserialize.</li><li><strong>secret_key</strong> – the secret key used to serialize the cookie.</li></ul></td></tr><tr class="field-even field"><th class="field-name">返回:</th><td class="field-body"><p class="first last">a new <a class="reference internal" href="#werkzeug.contrib.securecookie.SecureCookie" title="werkzeug.contrib.securecookie.SecureCookie"><tt class="xref py py-class docutils literal"><span class="pre">SecureCookie</span></tt></a>.</p></td></tr></tbody></table> *exception *werkzeug.contrib.securecookie.UnquoteError Internal exception used to signal failures on quoting.
';