diff options
author | David Lord <davidism@gmail.com> | 2023-04-28 09:24:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-28 09:24:27 -0700 |
commit | 447d4a8046c787a641c34aa9cdeedabc21b180e2 (patch) | |
tree | 5c2ccc2c605da856044d5a4a2768508e01514eb0 | |
parent | 5c32263a2ba135bad8b085087f4035b3c135f67e (diff) | |
parent | 18616d24dc4cce4973fbb6a55bcc5396c5add311 (diff) | |
download | werkzeug-447d4a8046c787a641c34aa9cdeedabc21b180e2.tar.gz |
cookie sets `Path=/` by default again (#2673)
-rw-r--r-- | CHANGES.rst | 2 | ||||
-rw-r--r-- | src/werkzeug/http.py | 5 | ||||
-rw-r--r-- | tests/test_http.py | 25 |
3 files changed, 19 insertions, 13 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index e47232fe..7dd5f1ba 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,8 @@ Unreleased - Parse the cookie ``Expires`` attribute correctly in the test client. :issue:`2669` - ``max_content_length`` can only be enforced on streaming requests if the server sets ``wsgi.input_terminated``. :issue:`2668` +- The cookie ``Path`` attribute is set to ``/`` by default again, to prevent clients + from falling back to RFC 6265's ``default-path`` behavior. :issue:`2672` Version 2.3.1 diff --git a/src/werkzeug/http.py b/src/werkzeug/http.py index b408c624..a2075c70 100644 --- a/src/werkzeug/http.py +++ b/src/werkzeug/http.py @@ -1341,7 +1341,7 @@ def dump_cookie( value: str = "", max_age: timedelta | int | None = None, expires: str | datetime | int | float | None = None, - path: str | None = None, + path: str | None = "/", domain: str | None = None, secure: bool = False, httponly: bool = False, @@ -1388,6 +1388,9 @@ def dump_cookie( .. _`cookie`: http://browsercookielimits.squawky.net/ + .. versionchanged:: 2.3.1 + The ``path`` parameter is ``/`` by default. + .. versionchanged:: 2.3 ``localhost`` and other names without a dot are allowed for the domain. A leading dot is ignored. diff --git a/tests/test_http.py b/tests/test_http.py index e82f869d..5ceb7ef5 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -452,10 +452,11 @@ class TestHTTPUtility: assert set(rv.split("; ")) == { "HttpOnly", "Max-Age=360", + "Path=/", 'foo="bar baz blub"', } - assert http.dump_cookie("key", "xxx/") == "key=xxx/" - assert http.dump_cookie("key", "xxx=") == "key=xxx=" + assert http.dump_cookie("key", "xxx/") == "key=xxx/; Path=/" + assert http.dump_cookie("key", "xxx=", path=None) == "key=xxx=" def test_bad_cookies(self): cookies = http.parse_cookie( @@ -478,7 +479,7 @@ class TestHTTPUtility: def test_cookie_quoting(self): val = http.dump_cookie("foo", "?foo") - assert val == "foo=?foo" + assert val == "foo=?foo; Path=/" assert http.parse_cookie(val)["foo"] == "?foo" assert http.parse_cookie(r'foo="foo\054bar"')["foo"] == "foo,bar" @@ -488,13 +489,13 @@ class TestHTTPUtility: def test_cookie_domain_resolving(self): val = http.dump_cookie("foo", "bar", domain="\N{SNOWMAN}.com") - assert val == "foo=bar; Domain=xn--n3h.com" + assert val == "foo=bar; Domain=xn--n3h.com; Path=/" def test_cookie_unicode_dumping(self): val = http.dump_cookie("foo", "\N{SNOWMAN}") h = datastructures.Headers() h.add("Set-Cookie", val) - assert h["Set-Cookie"] == 'foo="\\342\\230\\203"' + assert h["Set-Cookie"] == 'foo="\\342\\230\\203"; Path=/' cookies = http.parse_cookie(h["Set-Cookie"]) assert cookies["foo"] == "\N{SNOWMAN}" @@ -502,7 +503,7 @@ class TestHTTPUtility: def test_cookie_unicode_keys(self): # Yes, this is technically against the spec but happens val = http.dump_cookie("fö", "fö") - assert val == _wsgi_encoding_dance('fö="f\\303\\266"', "utf-8") + assert val == _wsgi_encoding_dance('fö="f\\303\\266"; Path=/') cookies = http.parse_cookie(val) assert cookies["fö"] == "fö" @@ -513,20 +514,20 @@ class TestHTTPUtility: def test_cookie_domain_encoding(self): val = http.dump_cookie("foo", "bar", domain="\N{SNOWMAN}.com") - assert val == "foo=bar; Domain=xn--n3h.com" + assert val == "foo=bar; Domain=xn--n3h.com; Path=/" val = http.dump_cookie("foo", "bar", domain="foo.com") - assert val == "foo=bar; Domain=foo.com" + assert val == "foo=bar; Domain=foo.com; Path=/" def test_cookie_maxsize(self): - val = http.dump_cookie("foo", "bar" * 1363) + val = http.dump_cookie("foo", "bar" * 1360 + "b") assert len(val) == 4093 with pytest.warns(UserWarning, match="cookie is too large"): - http.dump_cookie("foo", "bar" * 1364) + http.dump_cookie("foo", "bar" * 1360 + "ba") with pytest.warns(UserWarning, match="the limit is 512 bytes"): - http.dump_cookie("foo", "w" * 509, max_size=512) + http.dump_cookie("foo", "w" * 501, max_size=512) @pytest.mark.parametrize( ("samesite", "expected"), @@ -538,7 +539,7 @@ class TestHTTPUtility: ), ) def test_cookie_samesite_attribute(self, samesite, expected): - value = http.dump_cookie("foo", "bar", samesite=samesite) + value = http.dump_cookie("foo", "bar", samesite=samesite, path=None) assert value == expected def test_cookie_samesite_invalid(self): |