"Gratuitous"? incompatibilities in the "fix only" releases
Yesterday I upgraded one of my computer to 2.7.10 and a program working for years failed.
The problem is this:
"""
http=httplib.HTTPConnection("127.0.0.1",8081)
http.request("GET","/XXXXX/%f" %last_t, "",
{"Authorization":"Basic %s" %base64.encodestring("%s:%s" %(a,b))})
"""
base64.encodestring() creates base64 encoding with a final '\n'. This used to work until 2.7.9 but 2.7.10 if failing now with an exception about an "illegal character" in a header.
I know that that code is faulty and I should drop the final '\n' or just use "base64.b64encode()" (my current fix). The point, thought, it that this code used to work in previous 2.7 releases but it is failing under 2.7.10.
This incompatible change will be released in 3.4.4 too.
I agree that new code is better, no argument here. My program was incorrect, sure. But I was under the impression that backwards incompatible code was forbidden in minor releases, except for very critical reasons (like the HTTPS security default backported to 2.7). I think that breaking working code during minor updates is risky and breaks user/programmer expectations.
The change was done in <https://bugs.python.org/issue22928>.
I think the change is the way to go, I don't ask for a revert (since 2.7.10 is already in the wild I want to keep it too in future 3.4.4) but I am interested in knowing the official statement of committers about backwards incompatible changes in minor releases for my own future reference.
Sorry if this email seems confrontational. Not my intention, but my English is getting worse by the day :-). This is an inquiry about policy, not an attack.
Thanks!
-- Jesús Cea Avión _/_/ _/_/_/ _/_/_/ jcea@jcea.es - http://www.jcea.es/ _/_/ _/_/ _/_/ _/_/ _/_/ Twitter: @jcea _/_/ _/_/ _/_/_/_/_/ jabber / xmpp:jcea@jabber.org _/_/ _/_/ _/_/ _/_/ _/_/ "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/ "El amor es poner tu felicidad en la felicidad de otro" - Leibniz
I believe that in this particular case, the bug was fixed (by tightening the requirements for headers) because the bug can lead to security vulnerabilities. I think you can find more by Googling for keywords like "http header injection". The more recent Python 2.7 bugfix releases have specific exemptions from the backwards compatibility requirements for security fixes -- because their lifespan will still be many years (EOL of 2.7 is summer 2020).
On Wed, Jul 29, 2015 at 6:06 PM, Jesus Cea <jcea@jcea.es> wrote:
Yesterday I upgraded one of my computer to 2.7.10 and a program working for years failed.
The problem is this:
""" http=httplib.HTTPConnection("127.0.0.1",8081) http.request("GET","/XXXXX/%f" %last_t, "",
{"Authorization":"Basic %s" %base64.encodestring("%s:%s" %(a,b))}) """base64.encodestring() creates base64 encoding with a final '\n'. This used to work until 2.7.9 but 2.7.10 if failing now with an exception about an "illegal character" in a header.
I know that that code is faulty and I should drop the final '\n' or just use "base64.b64encode()" (my current fix). The point, thought, it that this code used to work in previous 2.7 releases but it is failing under 2.7.10.
This incompatible change will be released in 3.4.4 too.
I agree that new code is better, no argument here. My program was incorrect, sure. But I was under the impression that backwards incompatible code was forbidden in minor releases, except for very critical reasons (like the HTTPS security default backported to 2.7). I think that breaking working code during minor updates is risky and breaks user/programmer expectations.
The change was done in <https://bugs.python.org/issue22928>.
I think the change is the way to go, I don't ask for a revert (since 2.7.10 is already in the wild I want to keep it too in future 3.4.4) but I am interested in knowing the official statement of committers about backwards incompatible changes in minor releases for my own future reference.
Sorry if this email seems confrontational. Not my intention, but my English is getting worse by the day :-). This is an inquiry about policy, not an attack.
Thanks!
-- Jesús Cea Avión _/_/ _/_/_/ _/_/_/ jcea@jcea.es - http://www.jcea.es/ _/_/ _/_/ _/_/ _/_/ _/_/ Twitter: @jcea _/_/ _/_/ _/_/_/_/_/ jabber / xmpp:jcea@jabber.org _/_/ _/_/ _/_/ _/_/ _/_/ "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/ "El amor es poner tu felicidad en la felicidad de otro" - Leibniz
python-committers mailing list python-committers@python.org https://mail.python.org/mailman/listinfo/python-committers
-- --Guido van Rossum (python.org/~guido)
On 30 July 2015 at 04:50, Guido van Rossum <guido@python.org> wrote:
I believe that in this particular case, the bug was fixed (by tightening the requirements for headers) because the bug can lead to security vulnerabilities. I think you can find more by Googling for keywords like "http header injection". The more recent Python 2.7 bugfix releases have specific exemptions from the backwards compatibility requirements for security fixes -- because their lifespan will still be many years (EOL of 2.7 is summer 2020).
Yeah - this is a security issue, and unfortunately its one that can break programs [or rather, expose how they were broken already at an earlier and less susceptible point].
As a new committer, I'd like to double check my understanding of the policy:
https://docs.python.org/devguide/devcycle.html#maintenance-branches "... The only changes allowed to occur in a maintenance branch without debate are bug fixes. Also, a general rule for maintenance branches is that compatibility must not be broken at any point between sibling minor releases (3.4.1, 3.4.2, etc.). For both rules, only rare exceptions are accepted and must be discussed first."
Where should these things be discussed? I've been discussing with other committers on the issues in the issue tracker. Is this sufficient? What is the social norm?
https://docs.python.org/devguide/devcycle.html#security-branches "...The only changes made to a security branch are those fixing issues exploitable by attackers such as crashes, privilege escalation and, optionally, other issues such as denial of service attacks. Any other changes are not considered a security risk and thus not backported to a security branch."
This page doesn't specify the exception for 2.7, and by my poor reading of it the http issue wouldn't pass muster - but I think it was appropriate to apply. So I'm confused. Help :).
-Rob
On Jul 29, 2015 11:08 AM, "Robert Collins" <robertc@robertcollins.net> wrote:
On 30 July 2015 at 04:50, Guido van Rossum <guido@python.org> wrote:
The more recent Python 2.7 bugfix releases have specific exemptions from the backwards compatibility requirements for security fixes -- because their lifespan will still be many years (EOL
of
2.7 is summer 2020). [snip] https://docs.python.org/devguide/devcycle.html#security-branches "...The only changes made to a security branch are those fixing issues exploitable by attackers such as crashes, privilege escalation and, optionally, other issues such as denial of service attacks. Any other changes are not considered a security risk and thus not backported to a security branch."
This page doesn't specify the exception for 2.7, and by my poor reading of it the http issue wouldn't pass muster - but I think it was appropriate to apply. So I'm confused. Help :).
See PEP 466.
https://www.python.org/dev/peps/pep-0466/
-eric
On 30 July 2015 at 05:20, Eric Snow <ericsnowcurrently@gmail.com> wrote:
On Jul 29, 2015 11:08 AM, "Robert Collins" <robertc@robertcollins.net> wrote:
The more recent Python 2.7 bugfix releases have specific exemptions from the backwards compatibility requirements for security fixes -- because their lifespan will still be many years (EOL of 2.7 is summer 2020). [snip] https://docs.python.org/devguide/devcycle.html#security-branches "...The only changes made to a security branch are those fixing issues exploitable by attackers such as crashes, privilege escalation and,
On 30 July 2015 at 04:50, Guido van Rossum <guido@python.org> wrote: optionally, other issues such as denial of service attacks. Any other changes are not considered a security risk and thus not backported to a security branch."
This page doesn't specify the exception for 2.7, and by my poor reading of it the http issue wouldn't pass muster - but I think it was appropriate to apply. So I'm confused. Help :).
See PEP 466.
Thanks - but that doesn't cover the 22928 fix as far as I can tell. It explicitly says in fact that its not carte blanch, and that things still need to be discussed....
and I'm still not clear where we should discuss them :)
-Rob
-- Robert Collins <rbtcollins@hp.com> Distinguished Technologist HP Converged Cloud
When in doubt, such discussions should be escalated to python-dev. I don't know if this one was, though I vaguely recall seeing it discussed somewhere. Anyway, since it's been released, it should stay in.
On Wed, Jul 29, 2015 at 7:31 PM, Robert Collins <robertc@robertcollins.net> wrote:
On 30 July 2015 at 05:20, Eric Snow <ericsnowcurrently@gmail.com> wrote:
On Jul 29, 2015 11:08 AM, "Robert Collins" <robertc@robertcollins.net> wrote:
The more recent Python 2.7 bugfix releases have specific exemptions from the backwards compatibility requirements for security fixes -- because their lifespan will still be many years (EOL of 2.7 is summer 2020). [snip] https://docs.python.org/devguide/devcycle.html#security-branches "...The only changes made to a security branch are those fixing issues exploitable by attackers such as crashes, privilege escalation and,
On 30 July 2015 at 04:50, Guido van Rossum <guido@python.org> wrote: optionally, other issues such as denial of service attacks. Any other changes are not considered a security risk and thus not backported to a security branch."
This page doesn't specify the exception for 2.7, and by my poor reading of it the http issue wouldn't pass muster - but I think it was appropriate to apply. So I'm confused. Help :).
See PEP 466.
Thanks - but that doesn't cover the 22928 fix as far as I can tell. It explicitly says in fact that its not carte blanch, and that things still need to be discussed....
and I'm still not clear where we should discuss them :)
-Rob
-- Robert Collins <rbtcollins@hp.com> Distinguished Technologist HP Converged Cloud
-- --Guido van Rossum (python.org/~guido)
On 30 July 2015 at 03:50, Guido van Rossum <guido@python.org> wrote:
When in doubt, such discussions should be escalated to python-dev. I don't know if this one was, though I vaguely recall seeing it discussed somewhere. Anyway, since it's been released, it should stay in.
From a communications perspective, we may want to expand the https://docs.python.org/dev/whatsnew/2.7.html#new-features-added-to-python-2... backport documentation idea to also cover this kind of change that closes a network security hole, but may result in an exception in code that previously appeared to be doing the right thing.
Regards, Nick.
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On 7/29/2015 1:01 PM, Robert Collins wrote:
On 30 July 2015 at 04:50, Guido van Rossum <guido@python.org> wrote:
I believe that in this particular case, the bug was fixed (by tightening the requirements for headers) because the bug can lead to security vulnerabilities. I think you can find more by Googling for keywords like "http header injection". The more recent Python 2.7 bugfix releases have specific exemptions from the backwards compatibility requirements for security fixes -- because their lifespan will still be many years (EOL of 2.7 is summer 2020).
Yeah - this is a security issue, and unfortunately its one that can break programs [or rather, expose how they were broken already at an earlier and less susceptible point].
As a new committer, I'd like to double check my understanding of the policy:
https://docs.python.org/devguide/devcycle.html#maintenance-branches "... The only changes allowed to occur in a maintenance branch without debate are bug fixes. Also, a general rule for maintenance branches is that compatibility must not be broken at any point between sibling minor releases (3.4.1, 3.4.2, etc.).
Since bug fixes break code that depends on the bug (as happened in this case), the second rule appears to be written too strongly. It really needs a short paragraph. Bug fixes should only break code depending on the bug. Bug fixes must not change existing non-buggy features and should not introduce new features. Non-security bug fixes that break too much code deemed to be reasonable are sometimes deferred to the next release.
For both rules, only rare exceptions are accepted and must be discussed first."
Where should these things be discussed? I've been discussing with other committers on the issues in the issue tracker. Is this sufficient? What is the social norm?
Feature additions like adding a new parameter to fix a bug should be discussed on pydev. For instance, difflib.SequenceMatcher gained the autojunk parameter in 2.7.1. I believe the pydev discussion included "Is the issue a bug?" (yes) and "Does it need fixing in the current release?" (yes, it generated multiple bug reports). I believe being early in the long 2.7.x series and the last change to fix in 2.x played a role.
Terry
On Wed, 29 Jul 2015 13:41:09 -0400, Terry Reedy <tjreedy@udel.edu> wrote:
On 7/29/2015 1:01 PM, Robert Collins wrote:
On 30 July 2015 at 04:50, Guido van Rossum <guido@python.org> wrote:
I believe that in this particular case, the bug was fixed (by tightening the requirements for headers) because the bug can lead to security vulnerabilities. I think you can find more by Googling for keywords like "http header injection". The more recent Python 2.7 bugfix releases have specific exemptions from the backwards compatibility requirements for security fixes -- because their lifespan will still be many years (EOL of 2.7 is summer 2020).
Yeah - this is a security issue, and unfortunately its one that can break programs [or rather, expose how they were broken already at an earlier and less susceptible point].
As a new committer, I'd like to double check my understanding of the policy:
https://docs.python.org/devguide/devcycle.html#maintenance-branches "... The only changes allowed to occur in a maintenance branch without debate are bug fixes. Also, a general rule for maintenance branches is that compatibility must not be broken at any point between sibling minor releases (3.4.1, 3.4.2, etc.).
Since bug fixes break code that depends on the bug (as happened in this case), the second rule appears to be written too strongly. It really needs a short paragraph. Bug fixes should only break code depending on the bug. Bug fixes must not change existing non-buggy features and should not introduce new features. Non-security bug fixes that break too much code deemed to be reasonable are sometimes deferred to the next release.
No, I don't think it is too strong. Normally even code that depends on the bug should not be broken.
The calculus is necessarily a work of art: how likely is this bug fix to break working code? If the bug fixes something that previously raised an error, it is (usually) a no-brainer. If it fixes an erroneous result it is a judgement call based on how likely fixing it is to break working code, but usually it would get fixed. If it fixes an erroneous behavior it is again a judgement call, but weighted toward not going in to a maintenance release. Bugs judged too likely to break working code get fixed in feature releases (and mentioned in What's New).
For both rules, only rare exceptions are accepted and must be discussed first."
Where should these things be discussed? I've been discussing with other committers on the issues in the issue tracker. Is this sufficient? What is the social norm?
Usually the bug tracker is enough, with escalation to python-dev if there is a core-committer disagreement. For security issues, the security team should get involved in any decision, and their decision is pretty much final. I believe they automatically get notified if 'security' is selected for behavior...if not we should make it so.
Feature additions like adding a new parameter to fix a bug should be discussed on pydev. For instance, difflib.SequenceMatcher gained the autojunk parameter in 2.7.1. I believe the pydev discussion included "Is the issue a bug?" (yes) and "Does it need fixing in the current release?" (yes, it generated multiple bug reports). I believe being early in the long 2.7.x series and the last change to fix in 2.x played a role.
This would be a very exceptional case. I remember a discussion, I don't remember the approval of an API change. Changing the API in a minor release *except* for security issues is not normally acceptable. I'd be curious to read the reasoning behind this one.
So, the rule in the devguide is accurate, except that it should note that exceptions are made for fixing security related issues. That is, the calculus about not breaking working code is given a lot less weight, because the goal of the bug fix is to patch a security hole. We find it OK to break working code in order to make that code less vulnerable to a known attack. Although still try very hard *not* to break working code, if at all possible.
--David
On 29/07/15 18:50, Guido van Rossum wrote:
I believe that in this particular case, the bug was fixed (by tightening the requirements for headers) because the bug can lead to security vulnerabilities. I think you can find more by Googling for keywords like "http header injection". The more recent Python 2.7 bugfix releases have specific exemptions from the backwards compatibility requirements for security fixes -- because their lifespan will still be many years (EOL of 2.7 is summer 2020).
That argument is valuable but it fails when considering that this fix will be present in 3.4.4 too, with a normal EOL. I am OK with that, though. As I said, I sent my first message for policy verification and to raise awareness.
:-).
PS: I rarely read python-dev. Too much traffic for me :-(.
-- Jesús Cea Avión _/_/ _/_/_/ _/_/_/ jcea@jcea.es - http://www.jcea.es/ _/_/ _/_/ _/_/ _/_/ _/_/ Twitter: @jcea _/_/ _/_/ _/_/_/_/_/ jabber / xmpp:jcea@jabber.org _/_/ _/_/ _/_/ _/_/ _/_/ "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/ "El amor es poner tu felicidad en la felicidad de otro" - Leibniz
On Thu, 30 Jul 2015 00:11:53 +0200, Jesus Cea <jcea@jcea.es> wrote:
On 29/07/15 18:50, Guido van Rossum wrote:
I believe that in this particular case, the bug was fixed (by tightening the requirements for headers) because the bug can lead to security vulnerabilities. I think you can find more by Googling for keywords like "http header injection". The more recent Python 2.7 bugfix releases have specific exemptions from the backwards compatibility requirements for security fixes -- because their lifespan will still be many years (EOL of 2.7 is summer 2020).
That argument is valuable but it fails when considering that this fix will be present in 3.4.4 too, with a normal EOL. I am OK with that, though. As I said, I sent my first message for policy verification and to raise awareness.
No, the security bug fix conditional exception applies to all maintenance releases. The big (PEP required) exception for 2.7 was that the *API* changed in 2.7 in certain ways.
--David
For reference, a similar bug fix also introduced incompatibilities with the Chishop service: http://bugs.python.org/issue23899
On Jul 29, 2015, at 12:06, Jesus Cea <jcea@jcea.es<mailto:jcea@jcea.es>> wrote:
Yesterday I upgraded one of my computer to 2.7.10 and a program working for years failed.
The problem is this:
"""
http=httplib.HTTPConnection("127.0.0.1",8081)
http.request("GET","/XXXXX/%f" %last_t, "",
{"Authorization":"Basic %s" %base64.encodestring("%s:%s" %(a,b))})
"""
base64.encodestring() creates base64 encoding with a final '\n'. This used to work until 2.7.9 but 2.7.10 if failing now with an exception about an "illegal character" in a header.
I know that that code is faulty and I should drop the final '\n' or just use "base64.b64encode()" (my current fix). The point, thought, it that this code used to work in previous 2.7 releases but it is failing under 2.7.10.
This incompatible change will be released in 3.4.4 too.
I agree that new code is better, no argument here. My program was incorrect, sure. But I was under the impression that backwards incompatible code was forbidden in minor releases, except for very critical reasons (like the HTTPS security default backported to 2.7). I think that breaking working code during minor updates is risky and breaks user/programmer expectations.
The change was done in <https://bugs.python.org/issue22928>.
I think the change is the way to go, I don't ask for a revert (since 2.7.10 is already in the wild I want to keep it too in future 3.4.4) but I am interested in knowing the official statement of committers about backwards incompatible changes in minor releases for my own future reference.
Sorry if this email seems confrontational. Not my intention, but my English is getting worse by the day :-). This is an inquiry about policy, not an attack.
Thanks!
-- Jesús Cea Avión _/_/ _/_/_/ _/_/_/ jcea@jcea.es<mailto:jcea@jcea.es> - http://www.jcea.es/ _/_/ _/_/ _/_/ _/_/ _/_/ Twitter: @jcea _/_/ _/_/ _/_/_/_/_/ jabber / xmpp:jcea@jabber.org _/_/ _/_/ _/_/ _/_/ _/_/ "Things are not so easy" _/_/ _/_/ _/_/ _/_/ _/_/ _/_/ "My name is Dump, Core Dump" _/_/_/ _/_/_/ _/_/ _/_/ "El amor es poner tu felicidad en la felicidad de otro" - Leibniz
python-committers mailing list python-committers@python.org<mailto:python-committers@python.org> https://mail.python.org/mailman/listinfo/python-committers
participants (8)
-
Eric Snow
-
Guido van Rossum
-
Jason R. Coombs
-
Jesus Cea
-
Nick Coghlan
-
R. David Murray
-
Robert Collins
-
Terry Reedy