2265
The below demonstrative example uses an IP validator that splits up an IP address by octet, tests
to ensure each octet can be casted into an integer, and then returns the original IP address if no
exceptions are raised. This validated IP address is then tested using the "ping" command.
Example Language: Python (Bad)
import subprocess
def validate_ip(ip: str):
split_ip = ip.split('.')
if len(split_ip) > 4 or len(split_ip) == 0:
raise ValueError("Invalid IP length")
for octet in split_ip:
try:
int(octet, 10)
except ValueError as e:
raise ValueError(f"Cannot convert IP octet to int - {e}")
# Returns original IP after ensuring no exceptions are raised
return ip
def run_ping(ip: str):
validated = validate_ip(ip)
# The ping command treats zero-prepended IP addresses as octal
result = subprocess.call(["ping", validated])
print(result)
If run_ping() were to be called with one or more zero-prepended octets, validate_ip() will succeed
as zero-prepended numerical strings can be interpreted as decimal by a cast ("012" would cast to
12). However, as the original IP with the prepended zeroes is returned rather than the casted IP, it
will be used in the call to the ping command. Ping DOES check and support octal-based IP octets,
so the IP reached via ping may be different than the IP assumed by the validator. For example,
ping would considered "0127.0.0.1" the same as "87.0.0.1".
Example 2:
This code uses a regular expression to validate an IP string prior to using it in a call to the "ping"
command.
Example Language: Python (Bad)
import subprocess
import re
def validate_ip_regex(ip: str):
ip_validator = re.compile(r"((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}")
if ip_validator.match(ip):
return ip
else:
raise ValueError("IP address does not match valid pattern.")
def run_ping_regex(ip: str):
validated = validate_ip_regex(ip)
# The ping command treats zero-prepended IP addresses as octal
result = subprocess.call(["ping", validated])
print(result)
Since the regular expression does not have anchors (CWE-777), i.e. is unbounded without ^
or $ characters, then prepending a 0 or 0x to the beginning of the IP address will still result in a
matched regex pattern. Since the ping command supports octal and hex prepended IP addresses,
it will use the unexpectedly valid IP address (CWE-1389). For example, "0x63.63.63.63" would be
considered equivalent to "99.63.63.63". As a result, the attacker could potentially ping systems that
the attacker cannot reach directly.
Example 3:
Consider the following scenario, inspired by CWE team member Kelly Todd.
CWE Version 4.14
CWE-1389: Incorrect Parsing of Numbers with Different Radices
CWE-1389: Incorrect Parsing of Numbers with Different Radices