Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#24153 closed Cleanup/optimization (fixed)

Python change in casing of Cookie HttpOnly attribute broke some tests

Reported by: Jon Dufresne Owned by: nobody
Component: HTTP handling Version: dev
Severity: Normal Keywords:
Cc: cmawebsite@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

See http://tools.ietf.org/html/rfc6265#section-5.2.6

Relevant section:

5.2.6. The HttpOnly Attribute

If the attribute-name case-insensitively matches the string "HttpOnly", the user agent MUST append an attribute to the cookie- attribute-list with an attribute-name of HttpOnly and an empty attribute-value.

...

If the cookie-attribute-list contains an attribute with an attribute-name of "HttpOnly", set the cookie's http-only-flag to true. Otherwise, set the cookie's http-only-flag to false.

Django creates this attribute as httponly not HttpOnly.

It is true, this attribute is case insensitive when interpreted by the user agent, but it seems odd to me that Django would go out of its way to purposely use different case then stated in the standard. When looking at other web technologies, the case used in the standard is most typical. The examples in the standard also use the HttpOnly style.

PR to follow.

Change History (11)

comment:1 by Tim Graham, 9 years ago

Django's usage seems consistent with cpython so I'm not sure there's much benefit to changing this.

comment:2 by Berker Peksag, 9 years ago

If the spec says "HttpOnly attribute name MUST be case-sensitive", I'd agree with you. However, the grammar described HttpOnly and Secure as

secure-av         = "Secure"
httponly-av       = "HttpOnly"

http://tools.ietf.org/html/rfc6265#section-4.1.1

But again, it's not clear to me. If I'm not mistaken, we(and probably others) don't really follow accepted RFCs strictly for cookies.

The relevant Python issue is https://bugs.python.org/issue16611 You can also discuss this by creating a new issue at https://bugs.python.org/, but since RFC 6265 is not widely implemented and there is no practical issue, I think it may be rejected. And probably there is a backward compatibility issue.

There are a couple of RFC 6265 related issues:

comment:3 by Jon Dufresne, 9 years ago

When I originally opened this bug I wrongly assumed this bug was rooted in Django, not Python stdlib. If the feeling is that this should be resolved upstream, I can spend my efforts there. if you feel that is the best course of action, please let me know if I should close this ticket.

comment:4 by Jon Dufresne, 9 years ago

Resolution: invalid
Status: newclosed

I have moved this issue upstream http://bugs.python.org/issue23250.

comment:5 by Berker Peksag, 9 years ago

Just a note: The patch in issue 23250 has been committed to Python 3.4.3 and 3.5.0.

comment:6 by Tim Graham, 9 years ago

Resolution: invalid
Status: closednew
Summary: Cookie HttpOnly attribute does not use suggested case-style of HTTP standardPython change in casing of Cookie HttpOnly attribute broke some tests
Triage Stage: UnreviewedAccepted

We need to update some tests to be case insensitive:

diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
index 097cded..df9c40c 100644
--- a/django/contrib/sessions/tests.py
+++ b/django/contrib/sessions/tests.py
@@ -543,7 +543,7 @@ class SessionMiddlewareTests(unittest.TestCase):
         response = middleware.process_response(request, response)
         self.assertTrue(
             response.cookies[settings.SESSION_COOKIE_NAME]['httponly'])
-        self.assertIn('httponly',
+        self.assertIn('HttpOnly',
             str(response.cookies[settings.SESSION_COOKIE_NAME]))
 
     @override_settings(SESSION_COOKIE_HTTPONLY=False)
diff --git a/tests/requests/tests.py b/tests/requests/tests.py
index bb36af3..63e5eee 100644
--- a/tests/requests/tests.py
+++ b/tests/requests/tests.py
@@ -221,7 +221,7 @@ class RequestsTests(SimpleTestCase):
         example_cookie = response.cookies['example']
         # A compat cookie may be in use -- check that it has worked
         # both as an output string, and using the cookie attributes
-        self.assertIn('; httponly', str(example_cookie))
+        self.assertIn('; HttpOnly', str(example_cookie))
         self.assertTrue(example_cookie['httponly'])
 
     def test_unicode_cookie(self):

There's also this assertion in the session tests:

self.assertNotIn('httponly', str(response.cookies[settings.SESSION_COOKIE_NAME]))

Maybe the string could be a function of the Python version?

comment:7 by Tim Graham, 9 years ago

Has patch: set

comment:8 by Collin Anderson, 9 years ago

Cc: cmawebsite@… added
Triage Stage: AcceptedReady for checkin

comment:9 by Tim Graham <timograham@…>, 9 years ago

Resolution: fixed
Status: newclosed

In b19b81b3960ec2090d40be65547502a3386a769b:

Fixed #24153 -- Fixed cookie test compatibility with Python 3.4.3+

comment:10 by Tim Graham <timograham@…>, 9 years ago

In 06fa019c1bac6af934c0c5b7f93e5d837d96aefa:

[1.8.x] Fixed #24153 -- Fixed cookie test compatibility with Python 3.4.3+

Backport of b19b81b3960ec2090d40be65547502a3386a769b from master

comment:11 by Tim Graham <timograham@…>, 9 years ago

In 7a1ccc069971277d74fde143966de3f3d24c9a91:

[1.7.x] Fixed #24153 -- Fixed cookie test compatibility with Python 3.4.3+

Backport of b19b81b3960ec2090d40be65547502a3386a769b from master

Note: See TracTickets for help on using tickets.
Back to Top