PAC-X001 · no-default-return

No unconditional return at the end of FindProxyForURL

critical · Security and fail-safety · Top 20 #7

Some code path reaches the end of FindProxyForURL without a return. The function then returns undefined, and Chromium, Firefox and WinHTTP all connect directly. Traffic silently bypasses the proxy.

Why it matters

A PAC usually consists of exception branches followed by the default route. When the final return "PROXY ..." is missing, every host that matches none of the branches produces undefined. No engine raises a visible error: Chromium logs a script error and uses DIRECT, Firefox uses DIRECT, WinHTTP reports “no proxy”. The user sees working internet, the proxy sees nothing, and policy, logging and inspection are gone for exactly the traffic that should have gone through the proxy.

This is mechanism (a) of the “silent DIRECT” family. On networks whose firewall allows outbound 80/443 from clients (common where “the proxy handles policy”), the PAC is the only gate, and this bug opens it. The firewall should default-deny client egress so that PAC failures become loud instead of silent; the PAC itself must end with an unconditional return.

How to fix

End the function with an unconditional return of the intended default, e.g. return "PROXY proxy.corp.example:8080";

Examples

Bad

function FindProxyForURL(url, host) {
  if (dnsDomainIs(host, ".corp.example")) {
    return "DIRECT";
  }
}
Open bad example in checker

Good

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

Engine behaviour

EngineBehaviourSource
chromiumA non-string result is reported as "FindProxyForURL() did not return a string." and the evaluation fails (ERR_PAC_SCRIPT_FAILED); the request then falls back to DIRECT unless ProxyPacMandatory is set.code, verified 2026-10-04 · ref
firefoxundefined is treated as DIRECT.expert, unverified
pacparserReturns undefined to the caller (pactester prints "undefined").lab, verified 2026-05-20
winhttpReported as "no proxy", i.e. direct connection.expert, unverified

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