PAC-E019 · zscaler-unknown-pac-variable

Unknown Zscaler PAC variable

high · Errors and robustness

A Zscaler-hosted PAC file may contain variables such as ${GATEWAY} that the PAC server replaces before the browser sees the file. A misspelt or undocumented variable stays literal, the proxy entry becomes invalid and browsers skip it, which can mean a silent direct connection.

Why it matters

Zscaler documents a fixed set of variables for hosted PAC files: ${GATEWAY}, ${SECONDARY_GATEWAY}, ${COUNTRY_GATEWAY} and ${COUNTRY_SECONDARY_GATEWAY}, each optionally with _HOST, _F0 to _F7 or _FX, the subcloud forms (${GATEWAY.<subcloud>.<cloud>.net} and the SECONDARY, COUNTRY and COUNTRY SECONDARY variants, which use a dot between SECONDARY and GATEWAY), plus ${SRCIP}, ${COUNTRY} and, for Zscaler Client Connector, ${ZAPP_LOCAL_PROXY} and ${ZAPP_TUNNEL2_BYPASS}. Anything else, for example ${GATWAY} or ${GATEWAY_FX_HOST} with the suffixes in the wrong order, is not replaced. The browser then sees PROXY ${GATWAY}:80, which is not a valid host, and skips the entry. If it was the only entry, Chromium falls back to a direct connection (see PAC-E011). The variables are also only replaced when the file is hosted on the Zscaler cloud; in a self-hosted file every variable stays literal.

How to fix

Use the variable names exactly as documented (upper case, suffix order _HOST then _F0-_F7/_FX) and host the file on the Zscaler cloud; test with the Verify PAC File button in the admin console.

Examples

Bad

function FindProxyForURL(url, host) {
  if (isPlainHostName(host)) {
    return "DIRECT";
  }
  return "PROXY ${GATWAY}:80; PROXY ${SECONDARY_GATEWAY}:80";
}
Open bad example in checker

Good

function FindProxyForURL(url, host) {
  if (isPlainHostName(host)) {
    return "DIRECT";
  }
  return "PROXY ${GATEWAY}:80; PROXY ${SECONDARY_GATEWAY}:80";
}
Open good example in checker

Zscaler pack only (vendor = Zscaler in the checker).

Related rules

References