PAC-C012 · ipv6-not-handled

IPv4 loopback/private ranges handled, IPv6 equivalents not

info · Correctness

The PAC routes 127.0.0.0/8 or RFC 1918 literals DIRECT but has no equivalent for ::1, link-local or unique-local IPv6 addresses. IPv6 literal hosts take the default route, usually the proxy.

Why it matters

Engines pass IPv6 literals in host without brackets (e.g. ::1, fd00::10). An IPv4-only regex guard rejects them and isInNet cannot handle them, so local IPv6 services are sent to the proxy, where the connection typically fails. On dual-stack networks this shows up as “works with the IP, not with the hostname” tickets. Handling is limited: isInNetEx exists only in some engines (PAC-K003); string prefix checks on the well-known ranges are the portable option.

Draft until the bracket/no-bracket form of IPv6 literals in host has been confirmed per engine in the lab.

How to fix

Add host == "::1" and prefix checks for fe80: and fc00:/fd00: next to the IPv4 loopback/private rules, or document that IPv6 literals are intentionally proxied.

Examples

Bad

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

Good

function FindProxyForURL(url, host) {
  if (host == "::1" || shExpMatch(host, "fe80:*") || shExpMatch(host, "fd*:*")) {
    return "DIRECT";
  }
  if (/^\d+\.\d+\.\d+\.\d+$/.test(host) && isInNet(host, "127.0.0.0", "255.0.0.0")) {
    return "DIRECT";
  }
  return "PROXY proxy.corp.example:8080";
}
Open good example in checker

Related rules

References