mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-22 04:20:44 +00:00
Only allow IPv4 literals in strict form (#18656)
* Only allow IPv4 literals in strict form The strict form as defined in RFC 6943, section 3.1.1 only allows the dotted form ddd.ddd.ddd.ddd of IPv4 literals, where ddd is a one to three digit decimal number between 0 and 255. Until now octal numbers (with a leading zero) were interpreted as decimal numbers which has security implications, see CVE-2021-29922 and CVE-2021-29923. * Update lib/pure/net.nim Co-authored-by: Dominik Picheta <dominikpicheta@googlemail.com>
This commit is contained in:
@@ -281,14 +281,20 @@ proc parseIPv4Address(addressStr: string): IpAddress =
|
||||
byteCount = 0
|
||||
currentByte: uint16 = 0
|
||||
separatorValid = false
|
||||
leadingZero = false
|
||||
|
||||
result = IpAddress(family: IpAddressFamily.IPv4)
|
||||
|
||||
for i in 0 .. high(addressStr):
|
||||
if addressStr[i] in strutils.Digits: # Character is a number
|
||||
if leadingZero:
|
||||
raise newException(ValueError,
|
||||
"Invalid IP address. Octal numbers are not allowed")
|
||||
currentByte = currentByte * 10 +
|
||||
cast[uint16](ord(addressStr[i]) - ord('0'))
|
||||
if currentByte > 255'u16:
|
||||
if currentByte == 0'u16:
|
||||
leadingZero = true
|
||||
elif currentByte > 255'u16:
|
||||
raise newException(ValueError,
|
||||
"Invalid IP Address. Value is out of range")
|
||||
separatorValid = true
|
||||
@@ -300,6 +306,7 @@ proc parseIPv4Address(addressStr: string): IpAddress =
|
||||
currentByte = 0
|
||||
byteCount.inc
|
||||
separatorValid = false
|
||||
leadingZero = false
|
||||
else:
|
||||
raise newException(ValueError,
|
||||
"Invalid IP Address. Address contains an invalid character")
|
||||
@@ -388,10 +395,16 @@ proc parseIPv6Address(addressStr: string): IpAddress =
|
||||
result.address_v6[groupCount*2+1] = cast[uint8](currentShort and 0xFF)
|
||||
groupCount.inc()
|
||||
else: # Must parse IPv4 address
|
||||
var leadingZero = false
|
||||
for i, c in addressStr[v4StartPos..high(addressStr)]:
|
||||
if c in strutils.Digits: # Character is a number
|
||||
if leadingZero:
|
||||
raise newException(ValueError,
|
||||
"Invalid IP address. Octal numbers not allowed")
|
||||
currentShort = currentShort * 10 + cast[uint32](ord(c) - ord('0'))
|
||||
if currentShort > 255'u32:
|
||||
if currentShort == 0'u32:
|
||||
leadingZero = true
|
||||
elif currentShort > 255'u32:
|
||||
raise newException(ValueError,
|
||||
"Invalid IP Address. Value is out of range")
|
||||
separatorValid = true
|
||||
@@ -402,6 +415,7 @@ proc parseIPv6Address(addressStr: string): IpAddress =
|
||||
currentShort = 0
|
||||
byteCount.inc()
|
||||
separatorValid = false
|
||||
leadingZero = false
|
||||
else: # Invalid character
|
||||
raise newException(ValueError,
|
||||
"Invalid IP Address. Address contains an invalid character")
|
||||
@@ -431,7 +445,12 @@ proc parseIPv6Address(addressStr: string): IpAddress =
|
||||
|
||||
proc parseIpAddress*(addressStr: string): IpAddress =
|
||||
## Parses an IP address
|
||||
## Raises ValueError on error
|
||||
##
|
||||
## Raises ValueError on error.
|
||||
##
|
||||
## For IPv4 addresses, only the strict form as
|
||||
## defined in RFC 6943 is considered valid, see
|
||||
## https://datatracker.ietf.org/doc/html/rfc6943#section-3.1.1.
|
||||
if addressStr.len == 0:
|
||||
raise newException(ValueError, "IP Address string is empty")
|
||||
if addressStr.contains(':'):
|
||||
|
||||
@@ -50,6 +50,41 @@ block: # parseIpAddress tests
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("gggg:cdba:0000:0000:0000:0000:3257:9652")
|
||||
|
||||
block: # ipv4-compatible ipv6 address (embedded ipv4 address)
|
||||
check parseIpAddress("::ffff:10.0.0.23") == parseIpAddress("::ffff:0a00:0017")
|
||||
|
||||
block: # octal number in ipv4 address
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("010.8.8.8")
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("8.010.8.8")
|
||||
|
||||
block: # hexadecimal number in ipv4 address
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("0xc0.168.0.1")
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("192.0xa8.0.1")
|
||||
|
||||
block: # less than 4 numbers in ipv4 address
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("127.0.1")
|
||||
|
||||
block: # octal number in embedded ipv4 address
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("::ffff:010.8.8.8")
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("::ffff:8.010.8.8")
|
||||
|
||||
block: # hexadecimal number in embedded ipv4 address
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("::ffff:0xc0.168.0.1")
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("::ffff:192.0xa8.0.1")
|
||||
|
||||
block: # less than 4 numbers in embedded ipv4 address
|
||||
expect(ValueError):
|
||||
discard parseIpAddress("::ffff:127.0.1")
|
||||
|
||||
block: # "IpAddress/Sockaddr conversion"
|
||||
proc test(ipaddrstr: string) =
|
||||
var ipaddr_1 = parseIpAddress(ipaddrstr)
|
||||
|
||||
@@ -8,23 +8,23 @@ const
|
||||
positives = [
|
||||
"::f:8:a8f:218.17.235.229",
|
||||
"::b:228.19.241.2",
|
||||
"::8:c:a:f:8.35.8.096",
|
||||
"::3:e:a:bc:04.19.2.9",
|
||||
"::8:c:a:f:8.35.8.96",
|
||||
"::3:e:a:bc:4.19.2.9",
|
||||
"::2:212.242.248.19",
|
||||
"::df:a5f:3.250.208.9",
|
||||
"::8:c:5:e63:250.208.249.0",
|
||||
"::b:f:181.12.9.98",
|
||||
"::a:f8:77.08.243.232",
|
||||
"::a:b:85:e4d9:252.9.229.056",
|
||||
"::a:f8:77.8.243.232",
|
||||
"::a:b:85:e4d9:252.9.229.56",
|
||||
"941:c:8a:c:e::917",
|
||||
"e8:7a:e:ad:88a:8:203.235.225.46",
|
||||
"139c:9e::f8:254.08.21.249",
|
||||
"139c:9e::f8:254.8.21.249",
|
||||
"b38:f0:e::f9:89.6.12.18",
|
||||
"ef::8",
|
||||
"5::ab",
|
||||
"a::8:255.247.96.253",
|
||||
"b:c0::c:254.248.95.254",
|
||||
"::8c:2:99.251.024.3",
|
||||
"::8c:2:99.251.24.3",
|
||||
"98::c:247.240.249.57",
|
||||
"9::9",
|
||||
"628::f1ed:f",
|
||||
@@ -106,68 +106,68 @@ const
|
||||
"::315",
|
||||
"::a:a",
|
||||
"::aed3:a",
|
||||
"f0eb:0:e8:b:c:a:254.098.233.17",
|
||||
"f0eb:0:e8:b:c:a:254.98.233.17",
|
||||
"bfa:7fc:c66d:15:e9a:ded:254.119.9.9",
|
||||
"d:ffa8:9:a:879:3:202.39.08.245",
|
||||
"d:ffa8:9:a:879:3:202.39.8.245",
|
||||
"8e:2:8:fa8a:f1d1:1aa8:252.254.245.81",
|
||||
"5:d4:a:e9:8:8:06.38.98.253",
|
||||
"9c5:4:a5c:f:a6:8c9d:05.250.8.2",
|
||||
"5:d4:a:e9:8:8:6.38.98.253",
|
||||
"9c5:4:a5c:f:a6:8c9d:5.250.8.2",
|
||||
"d19a:2:f808:be:f:c:98.86.197.249",
|
||||
"8:26ac:8:8:cb:f:242.00.254.85",
|
||||
"8:26ac:8:8:cb:f:242.0.254.85",
|
||||
"38:e:1:0b88:f:0:8.89.248.92",
|
||||
"e7:ff96:a:f:f:b:253.91.052.195",
|
||||
"e7:ff96:a:f:f:b:253.91.52.195",
|
||||
"d:8:2:5:894:5:254.0.240.199",
|
||||
"2:98:9:8aa:9c8f:fa:252.98.248.17",
|
||||
"e9:d4f:890:ccbe:5:8:088.200.228.216",
|
||||
"e9:d4f:890:ccbe:5:8:88.200.228.216",
|
||||
"3:3:9:5:6a:df5:255.251.8.12",
|
||||
"0280:3:8:8:4:9:255.000.251.249",
|
||||
"0280:3:8:8:4:9:255.0.251.249",
|
||||
"8:af7:db:aa:0:9:238.248.250.255",
|
||||
"ff:ee:9a:9252:a:289:059.083.18.255",
|
||||
"ff:ee:9a:9252:a:289:59.83.18.255",
|
||||
"9f6:5:fc9:b:a89:a:142.1.250.254",
|
||||
"e:981a:da:bf94:9:f8:254.242.18.95",
|
||||
"3c:1:4:f2:89:f:8.91.255.14",
|
||||
"e::9a2:c:9.050.80.8",
|
||||
"e::9a2:c:9.50.80.8",
|
||||
"9::4a:07:fb:211.241.254.228",
|
||||
"9be::2:e:215.189.48.188",
|
||||
"f::f:d:069.148.99.168",
|
||||
"f::f:d:69.148.99.168",
|
||||
"f::a:97.18.240.47",
|
||||
"c::a98e:1:251.253.252.254",
|
||||
"668::82:214.87.208.9",
|
||||
"9c0::cf0:ecb:253.208.238.255",
|
||||
"a::0:f1:210.240.238.049",
|
||||
"8::a:1:251.238.34.09",
|
||||
"a::0:f1:210.240.238.49",
|
||||
"8::a:1:251.238.34.9",
|
||||
"81:dfe::b8:8.255.249.248",
|
||||
"d3::7:b:9:83.189.08.244",
|
||||
"8::9:8:8:00.7.11.252",
|
||||
"d3::7:b:9:83.189.8.244",
|
||||
"8::9:8:8:0.7.11.252",
|
||||
"2:8::c:a8:250.221.9.249",
|
||||
"2::f:99.8.249.247",
|
||||
"c:22f5::5:2c:243.15.79.89",
|
||||
"e:8e::da:251.243.255.2",
|
||||
"f15f:9::a:255.70.247.218",
|
||||
"f:b::9f38:31.220.94.022",
|
||||
"9::9a48:03.98.249.119",
|
||||
"f:b::9f38:31.220.94.22",
|
||||
"9::9a48:3.98.249.119",
|
||||
"d:d:9b87::2d:a:249.253.38.8",
|
||||
"d86d:99b::a9b:5:242.236.8.244",
|
||||
"eb:3::f:9cf:1.253.1.228",
|
||||
"b::ba2:255.247.114.64",
|
||||
"2f:ec:bcb::9:219.254.250.094",
|
||||
"2f:ec:bcb::9:219.254.250.94",
|
||||
"da8a:f6::a:e0:19.251.241.251",
|
||||
"5e:c1::a:021.250.8.254",
|
||||
"5e:c1::a:21.250.8.254",
|
||||
"c:9::8c9b:248.219.212.252",
|
||||
"2:a::8d4a:216.255.198.223",
|
||||
"1f::66:255.30.08.150",
|
||||
"1f::66:255.30.8.150",
|
||||
"bc2b:8f::2ff9:6.245.99.230",
|
||||
"a:8::a8:9.251.246.255",
|
||||
"f:7:7::98:06.14.1.208",
|
||||
"f:7:7::98:6.14.1.208",
|
||||
"e:2::9:218.249.255.254",
|
||||
"79:f::6:250.255.98.246",
|
||||
"47:9:fb9f::9:038.136.17.251",
|
||||
"47:9:fb9f::9:38.136.17.251",
|
||||
"ed::a:247.9.23.239",
|
||||
"6f::f1:88.254.119.9",
|
||||
"a::d:218.199.236.0",
|
||||
"fc88::9:203.196.04.95",
|
||||
"::8.048.255.85",
|
||||
"::253.07.255.36",
|
||||
"fc88::9:203.196.4.95",
|
||||
"::8.48.255.85",
|
||||
"::253.7.255.36",
|
||||
"9:d::253.7.178.229",
|
||||
"::250.84.158.253",
|
||||
"::8.55.204.248",
|
||||
@@ -175,31 +175,39 @@ const
|
||||
"df9:88ca::248.255.108.17",
|
||||
"8e9b::250.206.0.82",
|
||||
"::209.8.254.209",
|
||||
"::247.088.8.8",
|
||||
"::247.88.8.8",
|
||||
"::cb:f:ba41:250.208.19.249",
|
||||
"::fe:0e8:243.240.229.5",
|
||||
"::c:223.251.5.226",
|
||||
"::8:08.03.8.250",
|
||||
"::8:8.3.8.250",
|
||||
"::f:8.88.11.255",
|
||||
"::fda:48:aa:05.189.07.2",
|
||||
"::8:c3f:f:240.06.212.255",
|
||||
"::fda:48:aa:5.189.7.2",
|
||||
"::8:c3f:f:240.6.212.255",
|
||||
"::f:0aa:244.123.99.16",
|
||||
"::c9b5:c:034.8.090.196",
|
||||
"::c9b5:c:34.8.90.196",
|
||||
"::98:c9:254.14.241.81"
|
||||
]
|
||||
negatives = ["foo.bar",
|
||||
"::::::::::::",
|
||||
"yet another failure",
|
||||
"de:6:c:ab5:6a::9:252.06.06.249",
|
||||
"f9:5f7:fa38:9:b::b6:09.255.248.252",
|
||||
"de:6:c:ab5:6a::9:252.6.6.249",
|
||||
"f9:5f7:fa38:9:b::b6:9.255.248.252",
|
||||
"97:c:5b:81:8a::f5dd:144.252.250.9",
|
||||
"9:8:cd:8:a9::f:247.255.09.255",
|
||||
"9:8:cd:8:a9::f:247.255.9.255",
|
||||
"18:1:8c:2:3::9:8.254.252.139",
|
||||
"e:c298:3:e:a::bb12:254.246.05.250",
|
||||
"e:c298:3:e:a::bb12:254.246.5.250",
|
||||
"e:e:c:8e:fd::8:253.8.49.231",
|
||||
"9:97f:f:e929:8a::c9:0.8.252.10",
|
||||
"0df:b24:7:89:c::2b:16.249.240.092",
|
||||
"0df:b24:7:89:c::2b:16.249.240.92",
|
||||
"b:8f5f:485:c:9a::84c:178.7.249.34",
|
||||
"::3:e:a:bc:091.19.2.9",
|
||||
"::a:f8:77.08.243.232",
|
||||
"::8c:2:99.251.029.3",
|
||||
"::8:c:a:f:8.35.8.096",
|
||||
"d:ffa8:9:a:879:3:0202.39.8.245",
|
||||
"139c:9e::f8:254.07.21.249",
|
||||
"f0eb:0:e8:b:c:a:254.233.043.17",
|
||||
"::a:b:85:e4d9:252.9.229.056",
|
||||
]
|
||||
|
||||
proc ok(pos: openarray[string]) =
|
||||
|
||||
Reference in New Issue
Block a user