Skip to content

Commit da37555

Browse files
miss-islingtonsethmlarsonhugovkserhiy-storchakagpshead
authored
[3.11] gh-128840: Limit the number of parts in IPv6 address parsing (GH-128841) (GH-134613)
Limit length of IP address string to 39 (cherry picked from commit 47f1161) Co-authored-by: Seth Michael Larson <seth@python.org> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Gregory P. Smith <greg@krypto.org>
1 parent f38f9cf commit da37555

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

Lib/ipaddress.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,8 +1664,16 @@ def _ip_int_from_string(cls, ip_str):
16641664
"""
16651665
if not ip_str:
16661666
raise AddressValueError('Address cannot be empty')
1667+
if len(ip_str) > 39:
1668+
msg = ("At most 39 characters expected in "
1669+
f"{ip_str[:14]!r}({len(ip_str)-28} chars elided){ip_str[-14:]!r}")
1670+
raise AddressValueError(msg)
16671671

1668-
parts = ip_str.split(':')
1672+
# We want to allow more parts than the max to be 'split'
1673+
# to preserve the correct error message when there are
1674+
# too many parts combined with '::'
1675+
_max_parts = cls._HEXTET_COUNT + 1
1676+
parts = ip_str.split(':', maxsplit=_max_parts)
16691677

16701678
# An IPv6 address needs at least 2 colons (3 parts).
16711679
_min_parts = 3
@@ -1685,7 +1693,6 @@ def _ip_int_from_string(cls, ip_str):
16851693
# An IPv6 address can't have more than 8 colons (9 parts).
16861694
# The extra colon comes from using the "::" notation for a single
16871695
# leading or trailing zero part.
1688-
_max_parts = cls._HEXTET_COUNT + 1
16891696
if len(parts) > _max_parts:
16901697
msg = "At most %d colons permitted in %r" % (_max_parts-1, ip_str)
16911698
raise AddressValueError(msg)

Lib/test/test_ipaddress.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,17 @@ def assertBadSplit(addr):
389389
# A trailing IPv4 address is two parts
390390
assertBadSplit("10:9:8:7:6:5:4:3:42.42.42.42%scope")
391391

392+
def test_bad_address_split_v6_too_long(self):
393+
def assertBadSplit(addr):
394+
msg = r"At most 39 characters expected in %s"
395+
with self.assertAddressError(msg, repr(re.escape(addr[:14]))):
396+
ipaddress.IPv6Address(addr)
397+
398+
# Long IPv6 address
399+
long_addr = ("0:" * 10000) + "0"
400+
assertBadSplit(long_addr)
401+
assertBadSplit(long_addr + "%zoneid")
402+
392403
def test_bad_address_split_v6_too_many_parts(self):
393404
def assertBadSplit(addr):
394405
msg = "Exactly 8 parts expected without '::' in %r"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Short-circuit the processing of long IPv6 addresses early in :mod:`ipaddress` to prevent excessive
2+
memory consumption and a minor denial-of-service.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy