Ticket #295 (closed defect: fixed)
paste/wsgiwrappers.py doesn't support HttpOnly cookies
| Reported by: | glyphobet | Owned by: | ianb |
|---|---|---|---|
| Priority: | normal | Milestone: | 1.4.1 |
| Component: | paste | Version: | svn-trunk |
| Severity: | normal | Keywords: | |
| Cc: | matt-paste@… |
Description
Support for the HttpOnly cookie attribute has been merged into the standard library's Cookie.py in Python 2.6: http://bugs.python.org/issue1638033
However, the WSGIResponse.set_cookie() method in paste/wsgiwrappers.py won't allow the user to set the httponly attribute on cookies.
There is another (closed) issue on this tracker that seems to indicate that HttpOnly cookies should be supported: http://trac.pythonpaste.org/pythonpaste/changeset/6937
The Pylons documentation also seems to indicate that HttpOnly cookies are intended to be supported: http://docs.pylonshq.com/thirdparty/webob.html http://pylonsbook.com/alpha1/getting_started
Here's the simplest possible patch to fix this issue. wsgiwrappers.py is identical in SVN, Paste 1.7.1, and Paste 1.4.2, so this patch can apply anywhere you like.
In order to test this patch, you will need a patched version of Cookie.py which supports HttpOnly, or a very recent release of Python 2.6/3.0.
This brings up a secondary issue which this patch does not address: If you try to set httponly=True while using Cookie.py from Python 2.5 or older, Cookie.py will raise a Cookie.CookieError exception.
The code in WSGIResponse.set_cookie() seems designed to prevent Cookie.py from raising CookieErrors by duplicating the list of allowed cookie attributes from Cookie.py. Since, with the improvement to Cookie.py in Python 2.6, the set of allowed attributes is no longer identical across all versions of Python, this no longer works.
I suggest one of these two options to fix the problem:
A) reading the list of allowed attributes out of the Cookie.Morsel._reserved dict and checking each key-word argument against that list in WSGIResponse.set_cookie()
if var_value is not None and var_value is not False:
var_name = var_name.replace('_', '-')
if Morsel._reserved.has_key(var_name):
self.cookies[key][var_name] = var_value
B) wrapping the attribute setting expression in a try block and catching and ignoring CookieError:
if var_value is not None and var_value is not False:
try:
self.cookies[key][var_name.replace('_', '-')] = var_value
except CookieError:
pass
C) removing the checking entirely. This would let Cookie.py keep track of which attributes are allowed and disallowed, and the calling code would have to ensure that it's not trying to set unsupported attributes.
Let me know which one of these you prefer and I will make the change, test it, and submit a new patch.

