Skip to content

Commit 47f1161

Browse files
sethmlarsonhugovkserhiy-storchakagpshead
authored
gh-128840: Limit the number of parts in IPv6 address parsing (GH-128841)
GH-128840: Limit the number of parts in IPv6 address parsing Limit length of IP address string to 39 --------- 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 973b8f6 commit 47f1161

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
@@ -1660,8 +1660,16 @@ def _ip_int_from_string(cls, ip_str):
16601660
"""
16611661
if not ip_str:
16621662
raise AddressValueError('Address cannot be empty')
1663+
if len(ip_str) > 39:
1664+
msg = ("At most 39 characters expected in "
1665+
f"{ip_str[:14]!r}({len(ip_str)-28} chars elided){ip_str[-14:]!r}")
1666+
raise AddressValueError(msg)
16631667

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

16661674
# An IPv6 address needs at least 2 colons (3 parts).
16671675
_min_parts = 3
@@ -1681,7 +1689,6 @@ def _ip_int_from_string(cls, ip_str):
16811689
# An IPv6 address can't have more than 8 colons (9 parts).
16821690
# The extra colon comes from using the "::" notation for a single
16831691
# leading or trailing zero part.
1684-
_max_parts = cls._HEXTET_COUNT + 1
16851692
if len(parts) > _max_parts:
16861693
msg = "At most %d colons permitted in %r" % (_max_parts-1, ip_str)
16871694
raise AddressValueError(msg)

Lib/test/test_ipaddress.py

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

400+
def test_bad_address_split_v6_too_long(self):
401+
def assertBadSplit(addr):
402+
msg = r"At most 39 characters expected in %s"
403+
with self.assertAddressError(msg, repr(re.escape(addr[:14]))):
404+
ipaddress.IPv6Address(addr)
405+
406+
# Long IPv6 address
407+
long_addr = ("0:" * 10000) + "0"
408+
assertBadSplit(long_addr)
409+
assertBadSplit(long_addr + "%zoneid")
410+
400411
def test_bad_address_split_v6_too_many_parts(self):
401412
def assertBadSplit(addr):
402413
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