diff options
author | Marcel Hellkamp <marc@gsites.de> | 2017-07-14 10:02:42 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-14 10:02:42 +0200 |
commit | 160765cce97b43d7110432562a20bf11eace9a47 (patch) | |
tree | 72dce649230a3afc04822c6ad047c4eef76cc1f7 | |
parent | ef5d2f41a109d0e3eb00b7c1786656a1cfb51962 (diff) | |
parent | 2d96ee2f40b55d576ae2810bf30b4417c976162b (diff) | |
download | bottle-160765cce97b43d7110432562a20bf11eace9a47.tar.gz |
Merge pull request #983 from provinzkraut/samesite-cookie
"SameSite" cookie feature (from issue #982)
-rwxr-xr-x | bottle.py | 14 | ||||
-rwxr-xr-x | docs/tutorial.rst | 1 |
2 files changed, 13 insertions, 2 deletions
@@ -128,7 +128,7 @@ if py3k: from urllib.parse import urljoin, SplitResult as UrlSplitResult from urllib.parse import urlencode, quote as urlquote, unquote as urlunquote urlunquote = functools.partial(urlunquote, encoding='latin1') - from http.cookies import SimpleCookie + from http.cookies import SimpleCookie, Morsel, CookieError from collections import MutableMapping as DictMixin import pickle from io import BytesIO @@ -1813,6 +1813,10 @@ class BaseResponse(object): :param secure: limit the cookie to HTTPS connections (default: off). :param httponly: prevents client-side javascript to read this cookie (default: off, requires Python 2.6 or newer). + :param same_site: disables third-party use for a cookie. + Allowed attributes: `lax` and `strict`. + In strict mode the cookie will never be sent. + In lax mode the cookie is only sent with a top-level GET request. If neither `expires` nor `max_age` is set (default), the cookie will expire at the end of the browser session (as soon as the browser @@ -1834,7 +1838,10 @@ class BaseResponse(object): """ if not self._cookies: self._cookies = SimpleCookie() - + + # To add "SameSite" cookie support. + Morsel._reserved['same-site'] = 'SameSite' + if secret: if not isinstance(value, basestring): depr(0, 13, "Pickling of arbitrary objects into cookies is " @@ -1863,6 +1870,9 @@ class BaseResponse(object): elif isinstance(value, (int, float)): value = time.gmtime(value) value = time.strftime("%a, %d %b %Y %H:%M:%S GMT", value) + # check values for SameSite cookie, because it's not natively supported by http.cookies. + if key == 'same_site' and value.lower() not in ('lax', 'strict'): + raise CookieError("Invalid attribute %r" % (key,)) if key in ('secure', 'httponly') and not value: continue self._cookies[name][key.replace('_', '-')] = value diff --git a/docs/tutorial.rst b/docs/tutorial.rst index 363c255..326e05d 100755 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -420,6 +420,7 @@ The :meth:`Response.set_cookie` method accepts a number of additional keyword ar * **path:** Limit the cookie to a given path (default: ``/``) * **secure:** Limit the cookie to HTTPS connections (default: off). * **httponly:** Prevent client-side javascript to read this cookie (default: off, requires Python 2.7 or newer). +* **same_site:** Disables third-party use for a cookie. Allowed attributes: `lax` and `strict`. In strict mode the cookie will never be sent. In lax mode the cookie is only sent with a top-level GET request. If neither `expires` nor `max_age` is set, the cookie expires at the end of the browser session or as soon as the browser window is closed. There are some other gotchas you should consider when using cookies: |