PAC-K021 · url-path-decision

Decision depends on the URL path or query

info · Compatibility across engines

The file chooses the route by the path or query of the URL. Chrome and Windows pass https URLs without path and query and Firefox passes no path at all, so such a test does not match there; Windows also reuses an earlier answer for the same host, even for http.

Why it matters

The url argument holds the whole address of the request, for example http://intranet.example/app/start?id=1. The part after the host name is the path (/app/start) and the query (?id=1). A PAC file that chooses a proxy by that part is fragile for two reasons.

For https addresses the path and query are private. Chrome (since version 52) passes only https://host/ to the PAC file, and in the lab on Windows 11 (2026-10-11) Windows did the same (https://host:port/). Firefox goes further and removes path and query from every address, http as well, unless a preference is changed. A test such as shExpMatch(url, "*/app/*") is therefore never true for an https request in those clients, and in Firefox never true at all.

For http addresses Windows keeps answers for a while. In the same lab run, later http requests to the same host, even with another path or another port, got the answer that the file had given for an earlier request; the file was not asked again. So the route that a path asks for is not reliable on Windows even without https.

The finding is information only and does not change the grade, because some deployments rely on path rules on purpose for http traffic in browsers. Choosing the route by host name is the reliable form; rules by path belong on the proxy, which sees the whole request.

How to fix

Decide by host (dnsDomainIs, shExpMatch(host, ...)) in the PAC file and move rules that need the path or query to the proxy.

Examples

Bad

function FindProxyForURL(url, host) {
  if (shExpMatch(url, "*/download/*")) {
    return "PROXY download-proxy.corp.example:8080";
  }
  return "PROXY proxy.corp.example:8080";
}
Open bad example in checker

Good

function FindProxyForURL(url, host) {
  if (dnsDomainIs(host, ".download.corp.example")) {
    return "PROXY download-proxy.corp.example:8080";
  }
  return "PROXY proxy.corp.example:8080";
}
Open good example in checker

Engine behaviour

EngineBehaviourSource
chromiumSince Chrome 52, https URLs reach the PAC file cut to scheme, host and port (SanitizeUrl); path and query are removed.code, verified 2026-10-04 · ref
firefoxPath and query are removed for every scheme, not only https (preference network.proxy.autoconfig_url.include_path, default false).code, verified 2026-10-04 · ref
winhttphttps URLs reach the script as https://host:port/. http URLs reach it whole, but later requests to the same host and scheme, also with another path or port, got an answer that the script had given for an earlier request.lab, verified 2026-10-11

Source: code = read in the engine's source, doc = vendor documentation, lab = observed in a lab run, expert = practitioner knowledge, not yet verified.

Related rules

References