PAC-X007 · substring-ip-prefix-match

String prefix used to match an IP range

high · Security and fail-safety · Top 20 #12

host.substring(0, 8) == "10.1.2.9" matches 10.1.2.99 and the hostname 10.1.2.9.evil.test. Prefix arithmetic on strings is not subnet arithmetic.

Why it matters

Octet boundaries are not character boundaries. host.substring(0,8) == "10.1.2.9" is true for 10.1.2.9, 10.1.2.90 to 10.1.2.99 and 10.1.2.9.evil.test. host.indexOf("10.") == 0 matches every string starting with 10., including hostnames such as 10.evil.test. The same applies to startsWith (which is also ES2015, PAC-K010). Address membership must be decided with isInNet on a dotted-quad.

How to fix

Use isInNet(host, "10.1.2.0", "255.255.255.0") on hosts that are IP literals; for hostnames use suffix matching on the domain.

Examples

Bad

function FindProxyForURL(url, host) {
  if (host.substring(0, 8) == "10.1.2.9") {
    return "DIRECT";
  }
  return "PROXY proxy.corp.example:8080";
}
Open bad example in checker

Good

function FindProxyForURL(url, host) {
  if (/^\d+\.\d+\.\d+\.\d+$/.test(host) && isInNet(host, "10.1.2.0", "255.255.255.0")) {
    return "DIRECT";
  }
  return "PROXY proxy.corp.example:8080";
}
Open good example in checker

Related rules

References