# HG changeset patch # User Julien Cristau # Date 1405433279 -7200 # Node ID 1245357b3b3e540a4e357151f851950152ad0d94 # Parent 4352b7ccde04c0c510975d0fc5edca6a11342134 [web] add support for HttpOnly cookie flag And use it for session cookies. Closes #4142521. diff -r 4352b7ccde04 -r 1245357b3b3e devtools/fake.py --- a/devtools/fake.py Fri Oct 17 18:16:58 2014 +0200 +++ b/devtools/fake.py Tue Jul 15 16:07:59 2014 +0200 @@ -65,8 +65,8 @@ super(FakeRequest, self).__init__(*args, **kwargs) self._session_data = {} - def set_cookie(self, name, value, maxage=300, expires=None, secure=False): - super(FakeRequest, self).set_cookie(name, value, maxage, expires, secure) + def set_cookie(self, name, value, maxage=300, expires=None, secure=False, httponly=False): + super(FakeRequest, self).set_cookie(name, value, maxage, expires, secure, httponly) cookie = self.get_response_header('Set-Cookie') self._headers_in.setHeader('Cookie', cookie) diff -r 4352b7ccde04 -r 1245357b3b3e web/application.py --- a/web/application.py Fri Oct 17 18:16:58 2014 +0200 +++ b/web/application.py Tue Jul 15 16:07:59 2014 +0200 @@ -224,7 +224,7 @@ sessioncookie = self.session_cookie(req) secure = req.https and req.base_url().startswith('https://') req.set_cookie(sessioncookie, session.sessionid, - maxage=None, secure=secure) + maxage=None, secure=secure, httponly=True) if not session.anonymous_session: self.session_manager.postlogin(req, session) return session diff -r 4352b7ccde04 -r 1245357b3b3e web/http_headers.py --- a/web/http_headers.py Fri Oct 17 18:16:58 2014 +0200 +++ b/web/http_headers.py Tue Jul 15 16:07:59 2014 +0200 @@ -934,9 +934,13 @@ #### Cookies. Blech! class Cookie(object): - # __slots__ = ['name', 'value', 'path', 'domain', 'ports', 'expires', 'discard', 'secure', 'comment', 'commenturl', 'version'] + # __slots__ = ['name', 'value', 'path', 'domain', 'ports', 'expires', + # 'discard', 'secure', 'httponly', 'comment', 'commenturl', + # 'version'] - def __init__(self, name, value, path=None, domain=None, ports=None, expires=None, discard=False, secure=False, comment=None, commenturl=None, version=0): + def __init__(self, name, value, path=None, domain=None, ports=None, + expires=None, discard=False, secure=False, httponly=False, + comment=None, commenturl=None, version=0): self.name = name self.value = value self.path = path @@ -945,6 +949,7 @@ self.expires = expires self.discard = discard self.secure = secure + self.httponly = httponly self.comment = comment self.commenturl = commenturl self.version = version @@ -955,7 +960,8 @@ if self.domain is not None: s+=", domain=%r" % (self.domain,) if self.ports is not None: s+=", ports=%r" % (self.ports,) if self.expires is not None: s+=", expires=%r" % (self.expires,) - if self.secure is not False: s+=", secure=%r" % (self.secure,) + if self.secure: s+=", secure" + if self.httponly: s+=", HttpOnly" if self.comment is not None: s+=", comment=%r" % (self.comment,) if self.commenturl is not None: s+=", commenturl=%r" % (self.commenturl,) if self.version != 0: s+=", version=%r" % (self.version,) @@ -1213,6 +1219,8 @@ out.append("domain=%s" % cookie.domain) if cookie.secure: out.append("secure") + if cookie.httponly: + out.append("HttpOnly") setCookies.append('; '.join(out)) return setCookies @@ -1240,6 +1248,8 @@ out.append("Port=%s" % quoteString(",".join([str(x) for x in cookie.ports]))) if cookie.secure: out.append("Secure") + if cookie.httponly: + out.append("HttpOnly") out.append('Version="1"') setCookies.append('; '.join(out)) return setCookies diff -r 4352b7ccde04 -r 1245357b3b3e web/request.py --- a/web/request.py Fri Oct 17 18:16:58 2014 +0200 +++ b/web/request.py Tue Jul 15 16:07:59 2014 +0200 @@ -569,7 +569,7 @@ except KeyError: return SimpleCookie() - def set_cookie(self, name, value, maxage=300, expires=None, secure=False): + def set_cookie(self, name, value, maxage=300, expires=None, secure=False, httponly=False): """set / update a cookie by default, cookie will be available for the next 5 minutes. @@ -595,7 +595,7 @@ expires = None # make sure cookie is set on the correct path cookie = Cookie(str(name), str(value), self.base_url_path(), - expires=expires, secure=secure) + expires=expires, secure=secure, httponly=httponly) self.headers_out.addHeader('Set-cookie', cookie) def remove_cookie(self, name, bwcompat=None): diff -r 4352b7ccde04 -r 1245357b3b3e web/test/unittest_web.py --- a/web/test/unittest_web.py Fri Oct 17 18:16:58 2014 +0200 +++ b/web/test/unittest_web.py Tue Jul 15 16:07:59 2014 +0200 @@ -117,6 +117,10 @@ webreq = self.web_request('/%d' % admin_eid) self.assertEqual(webreq.status, 200) + def test_session_cookie_httponly(self): + webreq = self.web_request() + self.assertIn('HttpOnly', webreq.getheader('set-cookie')) + class LogQueriesTC(CubicWebServerTC): @classmethod