String prefix used to match an IP range
high
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 checkerGood
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 checkerRelated rules
- IP range matched as a text prefix PAC-X006
- RFC 1918 range with the wrong mask PAC-C007