Skip to content

Commit 4c33997

Browse files
pizzapantherasvetlov
authored andcommitted
bpo-34911: Added support for secure websocket cookies (GH-9734)
1 parent af5658a commit 4c33997

File tree

4 files changed

+67
-5
lines changed

4 files changed

+67
-5
lines changed

Doc/library/http.cookiejar.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,16 @@ The following classes are provided:
7878
from / returned to the server.
7979

8080

81-
.. class:: DefaultCookiePolicy( blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False )
81+
.. class:: DefaultCookiePolicy( blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False, secure_protocols=("https", "wss") )
8282

8383
Constructor arguments should be passed as keyword arguments only.
8484
*blocked_domains* is a sequence of domain names that we never accept cookies
8585
from, nor return cookies to. *allowed_domains* if not :const:`None`, this is a
86-
sequence of the only domains for which we accept and return cookies. For all
87-
other arguments, see the documentation for :class:`CookiePolicy` and
88-
:class:`DefaultCookiePolicy` objects.
86+
sequence of the only domains for which we accept and return cookies.
87+
*secure_protocols* is a sequence of protocols for which secure cookies can be
88+
added to. By default *https* and *wss* (secure websocket) are considered
89+
secure protocols. For all other arguments, see the documentation for
90+
:class:`CookiePolicy` and :class:`DefaultCookiePolicy` objects.
8991

9092
:class:`DefaultCookiePolicy` implements the standard accept / reject rules for
9193
Netscape and :rfc:`2965` cookies. By default, :rfc:`2109` cookies (ie. cookies

Lib/http/cookiejar.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ def __init__(self,
878878
strict_ns_domain=DomainLiberal,
879879
strict_ns_set_initial_dollar=False,
880880
strict_ns_set_path=False,
881+
secure_protocols=("https", "wss")
881882
):
882883
"""Constructor arguments should be passed as keyword arguments only."""
883884
self.netscape = netscape
@@ -890,6 +891,7 @@ def __init__(self,
890891
self.strict_ns_domain = strict_ns_domain
891892
self.strict_ns_set_initial_dollar = strict_ns_set_initial_dollar
892893
self.strict_ns_set_path = strict_ns_set_path
894+
self.secure_protocols = secure_protocols
893895

894896
if blocked_domains is not None:
895897
self._blocked_domains = tuple(blocked_domains)
@@ -1116,7 +1118,7 @@ def return_ok_verifiability(self, cookie, request):
11161118
return True
11171119

11181120
def return_ok_secure(self, cookie, request):
1119-
if cookie.secure and request.type != "https":
1121+
if cookie.secure and request.type not in self.secure_protocols:
11201122
_debug(" secure cookie with non-secure request")
11211123
return False
11221124
return True

Lib/test/test_http_cookiejar.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,61 @@ def test_secure(self):
984984
c._cookies["www.acme.com"]["/"]["foo2"].secure,
985985
"secure cookie registered non-secure")
986986

987+
def test_secure_block(self):
988+
pol = DefaultCookiePolicy()
989+
c = CookieJar(policy=pol)
990+
991+
headers = ["Set-Cookie: session=narf; secure; path=/"]
992+
req = urllib.request.Request("https://www.acme.com/")
993+
res = FakeResponse(headers, "https://www.acme.com/")
994+
c.extract_cookies(res, req)
995+
self.assertEqual(len(c), 1)
996+
997+
req = urllib.request.Request("https://www.acme.com/")
998+
c.add_cookie_header(req)
999+
self.assertTrue(req.has_header("Cookie"))
1000+
1001+
req = urllib.request.Request("http://www.acme.com/")
1002+
c.add_cookie_header(req)
1003+
self.assertFalse(req.has_header("Cookie"))
1004+
1005+
# secure websocket protocol
1006+
req = urllib.request.Request("wss://www.acme.com/")
1007+
c.add_cookie_header(req)
1008+
self.assertTrue(req.has_header("Cookie"))
1009+
1010+
# non-secure websocket protocol
1011+
req = urllib.request.Request("ws://www.acme.com/")
1012+
c.add_cookie_header(req)
1013+
self.assertFalse(req.has_header("Cookie"))
1014+
1015+
def test_custom_secure_protocols(self):
1016+
pol = DefaultCookiePolicy(secure_protocols=["foos"])
1017+
c = CookieJar(policy=pol)
1018+
1019+
headers = ["Set-Cookie: session=narf; secure; path=/"]
1020+
req = urllib.request.Request("https://www.acme.com/")
1021+
res = FakeResponse(headers, "https://www.acme.com/")
1022+
c.extract_cookies(res, req)
1023+
self.assertEqual(len(c), 1)
1024+
1025+
# test https removed from secure protocol list
1026+
req = urllib.request.Request("https://www.acme.com/")
1027+
c.add_cookie_header(req)
1028+
self.assertFalse(req.has_header("Cookie"))
1029+
1030+
req = urllib.request.Request("http://www.acme.com/")
1031+
c.add_cookie_header(req)
1032+
self.assertFalse(req.has_header("Cookie"))
1033+
1034+
req = urllib.request.Request("foos://www.acme.com/")
1035+
c.add_cookie_header(req)
1036+
self.assertTrue(req.has_header("Cookie"))
1037+
1038+
req = urllib.request.Request("foo://www.acme.com/")
1039+
c.add_cookie_header(req)
1040+
self.assertFalse(req.has_header("Cookie"))
1041+
9871042
def test_quote_cookie_value(self):
9881043
c = CookieJar(policy=DefaultCookiePolicy(rfc2965=True))
9891044
interact_2965(c, "http://www.acme.com/", r'foo=\b"a"r; Version=1')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Added *secure_protocols* argument to *http.cookiejar.DefaultCookiePolicy* to
2+
allow for tweaking of protocols and also to add support by default for
3+
*wss*, the secure websocket protocol.

0 commit comments

Comments
 (0)