Repository navigation
2.7.18.16: httplib Content-Length / chunk-size validation (CVE-2026-103995) - #95
Merged
Merged
Conversation
…2026-103995) Backport of python/cpython pythonGH-150752 and pythonGH-159156 (pythongh-150751; the 3.10.22.1 ports are 833a27a and dbefda3). HTTPResponse parsed Content-Length with int() and chunk sizes with int(_, 16). Both accept input the RFC 9112 grammar forbids: a sign ("+5", "-5"), surrounding whitespace, and for base 16 an "0x" prefix. A peer that disagrees with httplib about message framing can use this for response splitting / desynchronisation. Values are now matched against Content-Length = 1*DIGIT and chunk-size = 1*HEXDIG first; an invalid Content-Length is ignored (the body is read to close) and an invalid chunk size closes the connection with IncompleteRead. Optional whitespace (SP/HTAB) around the Content-Length value is still allowed, per RFC 9112 section 5.1. 2.7.18.x: re has no fullmatch, so the patterns are anchored with \Z and used with match(). 2.7's int() never accepted underscores, but the grammar check covers them anyway. Tests use plain loops instead of subTest and also cover "0x5" as a Content-Length. Co-Authored-By: Claude Opus 5.5 <[email protected]>
ezequielp-activestate
approved these changes
Oct 28, 2026
ezequielp-activestate
left a comment
There was a problem hiding this comment.
No blockers.
-
Fix matches upstream. This is upstream pythonGH-150752 plus its follow-up pythonGH-159156 (optional whitespace around
Content-Length), carried over in full. Nothing later in upstream touches this code. -
Repro (canned responses through
HTTPResponse):input base this branch Content-Length: +5length 5 ignored, read to close Content-Length: 5(OWS)length 5 length 5 0x5/-1ignored ignored chunk size +5/0x5accepted ( hello)IncompleteReadchunk size -0accepted (empty body) IncompleteReadchunk size 5hellohello -
Tests:
test_httplib: 58 run, OK (12 skipped: this build has no_ssl).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of python/cpython pythongh-150751 (pythonGH-150752 + pythonGH-159156; CVE-2026-103995, PSF-2026-47) to 2.7.18.x. This is the same fix as in 3.10.22.1 (#87) and 3.9.25.1 (#88).
Problem:
httplib.HTTPResponseparsedContent-Lengthwithint()and chunk sizes withint(_, 16). Both accept values the RFC 9112 grammar forbids: a sign, whitespace, and0xin base 16. When httplib and a peer disagree about where a message ends, that mismatch can be used for response splitting.Fix: values are checked against
1*DIGIT/1*HEXDIGbefore conversion.Content-Lengthis ignored, and the body is read until the connection closes.IncompleteRead.Content-Lengthvalue is still accepted, per RFC 9112 §5.1.Behavior change: malformed lengths and chunk sizes such as
+5or0x10are now rejected. Well-behaved servers never send these.Tests:
test_malformed_content_length,test_content_length_with_whitespaceandtest_malformed_chunk_size. The malformed-input tests fail on 2.7.18.15. With the fix,test_httplibpasses 58/58, andtest_urllib2,test_urllib2_localnet,test_xmlrpc,test_urllib,test_httpserversandtest_wsgirefall pass.Part of 2.7.18.16. It targets the
2.7.18.16integration branch.