PAC-B014 · agent-intercepts-pac-direct-traffic

DIRECT in the PAC does not bypass the vendor's agent

info · Best practice and maintainability

With an SSE agent installed, the PAC is evaluated first by the application or OS, and the agent intercepts afterwards at the TCP or driver level. A DIRECT in the PAC therefore means "not through this proxy", not "not through the agent"; the destination also needs the agent's own bypass.

Why it matters

This is the interaction the vendor packs exist for. Zscaler: “Zscaler Client Connector intercepts any traffic heading to port 80 and port 443” in Tunnel mode, and domain bypasses must be configured in the App Profile PAC, IP bypasses as destination exclusions or VPN gateway bypasses. Netskope: the Client first connects directly and, with an on-premises proxy, “monitors for HTTP CONNECT requests”, resets matching connections and re-originates them through its tunnel. Skyhigh: “SCP can work with a PAC file without alterations”, forwards proxied requests when configured for the proxy port, and for sites the PAC sends direct “SCP is configured to bypass by port (80,443), or by destination IP, or by process”. Palo Alto Networks: the browser evaluates the PAC first, and GlobalProtect evaluates its split-tunnel rules for the rest. The finding is informational and appears when the PAC bypasses public destinations (or when you told the checker the PAC is distributed by an agent); it reminds you to mirror the exception in the agent’s configuration, where the vendor wants it.

How to fix

Mirror each public DIRECT destination in the agent's own bypass (ZCC app profile PAC / destination exclusions, Netskope steering exception, SCP bypass list, GlobalProtect split tunnel) or remove it from the PAC.

Examples

Bad

function FindProxyForURL(url, host) {
  if (isPlainHostName(host)) {
    return "DIRECT";
  }
  if (shExpMatch(host, "*.video-service.example.com")) {
    return "DIRECT";
  }
  return "PROXY ${GATEWAY}:80; PROXY ${SECONDARY_GATEWAY}:80";
}
Open bad example in checker

Good

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

Zscaler, Netskope, Skyhigh and Prisma Access packs (Cloudflare proxy endpoints are the no-agent deployment).

Related rules

References