File tree Expand file tree Collapse file tree 5 files changed +57
-6
lines changed
Misc/NEWS.d/next/Security Expand file tree Collapse file tree 5 files changed +57
-6
lines changed Original file line number Diff line number Diff line change @@ -104,8 +104,7 @@ write code that handles both IP versions correctly. Address objects are
104
104
1. A string in decimal-dot notation, consisting of four decimal integers in
105
105
the inclusive range 0--255, separated by dots (e.g. ``192.168.0.1 ``). Each
106
106
integer represents an octet (byte) in the address. Leading zeroes are
107
- tolerated only for values less than 8 (as there is no ambiguity
108
- between the decimal and octal interpretations of such strings).
107
+ not tolerated to prevent confusion with octal notation.
109
108
2. An integer that fits into 32 bits.
110
109
3. An integer packed into a :class: `bytes ` object of length 4 (most
111
110
significant octet first).
@@ -117,6 +116,18 @@ write code that handles both IP versions correctly. Address objects are
117
116
>>> ipaddress.IPv4Address(b ' \xC0\xA8\x00\x01 ' )
118
117
IPv4Address('192.168.0.1')
119
118
119
+
120
+ .. versionchanged :: 3.8
121
+
122
+ Leading zeros are tolerated, even in ambiguous cases that look like
123
+ octal notation.
124
+
125
+ .. versionchanged :: 3.8.12
126
+
127
+ Leading zeros are no longer tolerated and are treated as an error.
128
+ IPv4 address strings are now parsed as strict as glibc
129
+ :func: `~socket.inet_pton `.
130
+
120
131
.. attribute :: version
121
132
122
133
The appropriate version number: ``4 `` for IPv4, ``6 `` for IPv6.
Original file line number Diff line number Diff line change @@ -2307,3 +2307,19 @@ URL by the parser in :mod:`urllib.parse` preventing such attacks. The removal
2307
2307
characters are controlled by a new module level variable
2308
2308
``urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE ``. (See :issue: `43882 `)
2309
2309
2310
+
2311
+ Notable changes in Python 3.8.12
2312
+ ================================
2313
+
2314
+ Changes in the Python API
2315
+ -------------------------
2316
+
2317
+ Starting with Python 3.8.12 the :mod: `ipaddress ` module no longer accepts
2318
+ any leading zeros in IPv4 address strings. Leading zeros are ambiguous and
2319
+ interpreted as octal notation by some libraries. For example the legacy
2320
+ function :func: `socket.inet_aton ` treats leading zeros as octal notatation.
2321
+ glibc implementation of modern :func: `~socket.inet_pton ` does not accept
2322
+ any leading zeros.
2323
+
2324
+ (Originally contributed by Christian Heimes in :issue: `36384 `, and backported
2325
+ to 3.8 by Achraf Merzouki)
Original file line number Diff line number Diff line change @@ -1173,6 +1173,11 @@ def _parse_octet(cls, octet_str):
1173
1173
if len (octet_str ) > 3 :
1174
1174
msg = "At most 3 characters permitted in %r"
1175
1175
raise ValueError (msg % octet_str )
1176
+ # Handle leading zeros as strict as glibc's inet_pton()
1177
+ # See security bug bpo-36384
1178
+ if octet_str != '0' and octet_str [0 ] == '0' :
1179
+ msg = "Leading zeros are not permitted in %r"
1180
+ raise ValueError (msg % octet_str )
1176
1181
# Convert to integer (we know digits are legal)
1177
1182
octet_int = int (octet_str , 10 )
1178
1183
if octet_int > 255 :
Original file line number Diff line number Diff line change @@ -97,10 +97,23 @@ def pickle_test(self, addr):
97
97
class CommonTestMixin_v4 (CommonTestMixin ):
98
98
99
99
def test_leading_zeros (self ):
100
- self .assertInstancesEqual ("000.000.000.000" , "0.0.0.0" )
101
- self .assertInstancesEqual ("192.168.000.001" , "192.168.0.1" )
102
- self .assertInstancesEqual ("016.016.016.016" , "16.16.16.16" )
103
- self .assertInstancesEqual ("001.000.008.016" , "1.0.8.16" )
100
+ # bpo-36384: no leading zeros to avoid ambiguity with octal notation
101
+ msg = "Leading zeros are not permitted in '\d+'"
102
+ addresses = [
103
+ "000.000.000.000" ,
104
+ "192.168.000.001" ,
105
+ "016.016.016.016" ,
106
+ "192.168.000.001" ,
107
+ "001.000.008.016" ,
108
+ "01.2.3.40" ,
109
+ "1.02.3.40" ,
110
+ "1.2.03.40" ,
111
+ "1.2.3.040" ,
112
+ ]
113
+ for address in addresses :
114
+ with self .subTest (address = address ):
115
+ with self .assertAddressError (msg ):
116
+ self .factory (address )
104
117
105
118
def test_int (self ):
106
119
self .assertInstancesEqual (0 , "0.0.0.0" )
Original file line number Diff line number Diff line change
1
+ :mod: `ipaddress ` module no longer accepts any leading zeros in IPv4 address
2
+ strings. Leading zeros are ambiguous and interpreted as octal notation by
3
+ some libraries. For example the legacy function :func: `socket.inet_aton `
4
+ treats leading zeros as octal notatation. glibc implementation of modern
5
+ :func: `~socket.inet_pton ` does not accept any leading zeros. For a while
6
+ the :mod: `ipaddress ` module used to accept ambiguous leading zeros.
You can’t perform that action at this time.
0 commit comments