blob: 645895e95a1ac7bd202ad2d0dfcdba14e5bd5c32 [file] [log] [blame] [view]
Eric Roman5ee3be22019-05-23 17:09:271# Proxy support in Chrome
2
Eric Roman12667032019-06-03 18:38:193This document establishes basic proxy terminology and describes Chrome-specific
4proxy behaviors.
Eric Roman5ee3be22019-05-23 17:09:275
Eric Roman12667032019-06-03 18:38:196[TOC]
Eric Roman5ee3be22019-05-23 17:09:277
Eric Roman12667032019-06-03 18:38:198## Proxy server identifiers
Eric Roman5ee3be22019-05-23 17:09:279
Eric Roman12667032019-06-03 18:38:1910A proxy server is an intermediary used for network requests. A proxy server can
11be described by its address, along with the proxy scheme that should be used to
12communicate with it.
Eric Roman5ee3be22019-05-23 17:09:2713
Eric Roman12667032019-06-03 18:38:1914This can be written as a string using either the "PAC format" or the "URI
15format".
Eric Roman5ee3be22019-05-23 17:09:2716
Eric Roman12667032019-06-03 18:38:1917The PAC format is how one names a proxy server in [Proxy
18auto-config](https://en.wikipedia.org/wiki/Proxy_auto-config) scripts. For
19example:
20* `PROXY foo:2138`
21* `SOCKS5 foo:1080`
22* `DIRECT`
Eric Roman5ee3be22019-05-23 17:09:2723
Eric Roman12667032019-06-03 18:38:1924The "URI format" instead encodes the information as a URL. For example:
25* `foo:2138`
26* `http://foo:2138`
27* `socks5://foo:1080`
28* `direct://`
Eric Roman5ee3be22019-05-23 17:09:2729
Eric Roman12667032019-06-03 18:38:1930The port number is optional in both formats. When omitted, a per-scheme default
31is used.
Eric Roman5ee3be22019-05-23 17:09:2732
Eric Roman12667032019-06-03 18:38:1933See the [Proxy server schemes](#Proxy-server-schemes) section for details on
34what schemes Chrome supports, and how to write them in the PAC and URI formats.
Eric Roman5ee3be22019-05-23 17:09:2735
Eric Roman12667032019-06-03 18:38:1936Most UI surfaces in Chrome (including command lines and policy) expect URI
37formatted proxy server identifiers. However outside of Chrome, proxy servers
38are generally identified less precisely by just an address -- the proxy
39scheme is assumed based on context.
Eric Roman5ee3be22019-05-23 17:09:2740
Eric Roman12667032019-06-03 18:38:1941In Windows' proxy settings there are host and port fields for the
42"HTTP", "Secure", "FTP", and "SOCKS" proxy. With the exception of "SOCKS",
43those are all identifiers for insecure HTTP proxy servers (proxy scheme is
44assumed as HTTP).
Eric Roman5ee3be22019-05-23 17:09:2745
46## Proxy resolution
47
48Proxying in Chrome is done at the URL level.
49
50When the browser is asked to fetch a URL, it needs to decide which IP endpoint
51to send the request to. This can be either a proxy server, or the target host.
52
53This is called proxy resolution. The input to proxy resolution is a URL, and
Eric Roman12667032019-06-03 18:38:1954the output is an ordered list of [proxy server
55identifiers](#Proxy-server-identifiers).
Eric Roman5ee3be22019-05-23 17:09:2756
57What proxies to use can be described using either:
58
Eric Roman12667032019-06-03 18:38:1959* [Manual proxy settings](#Manual-proxy-settings) - proxy resolution is defined
60 using a declarative set of rules. These rules are expressed as a mapping from
61 URL scheme to proxy server identifier(s), and a list of proxy bypass rules for
62 when to go DIRECT instead of using the mapped proxy.
Eric Roman5ee3be22019-05-23 17:09:2763
64* PAC script - proxy resolution is defined using a JavaScript program, that is
Eric Roman12667032019-06-03 18:38:1965 invoked whenever fetching a URL to get the list of proxy server identifiers
66 to use.
Eric Roman5ee3be22019-05-23 17:09:2767
68* Auto-detect - the WPAD protocol is used to probe the network (using DHCP/DNS)
69 and possibly discover the URL of a PAC script.
70
71## Proxy server schemes
72
Eric Roman12667032019-06-03 18:38:1973When using an explicit proxy in the browser, multiple layers of the network
74request are impacted, depending on the scheme that is used. Some implications
75of the proxy scheme are:
Eric Roman5ee3be22019-05-23 17:09:2776
Eric Roman12667032019-06-03 18:38:1977* Is communication to the proxy done over a secure channel?
78* Is name resolution (ex: DNS) done client side, or proxy side?
79* What authentication schemes to the proxy server are supported?
80* What network traffic can be sent through the proxy?
81
82Chrome supports these proxy server schemes:
83
84* [DIRECT](#DIRECT-proxy-scheme)
85* [HTTP](#HTTP-proxy-scheme)
86* [HTTPS](#HTTPS-proxy-scheme)
87* [SOCKSv4](#SOCKSv4-proxy-scheme)
88* [SOCKSv5](#SOCKSv5-proxy-scheme)
Eric Roman5ee3be22019-05-23 17:09:2789
90### DIRECT proxy scheme
91
92* Default port: N/A (neither host nor port are applicable)
93* Example identifier (PAC): `DIRECT`
94* Example identifier (URI): `direct://`
95
96This is a pseudo proxy scheme that indicates instead of using a proxy we are
97sending the request directly to the target server.
98
99It is imprecise to call this a "proxy server", but it is a convenient abstraction.
100
101### HTTP proxy scheme
102
103* Default port: 80
104* Example identifier (PAC): `PROXY proxy:8080`, `proxy` (non-standard; don't use)
105* Example identifiers (URI): `http://proxy:8080`, `proxy:8080` (can omit scheme)
106
107Generally when one refers to a "proxy server" or "web proxy", they are talking
108about an HTTP proxy.
109
110When using an HTTP proxy in Chrome, name resolution is always deferred to the
111proxy. HTTP proxies can proxy `http://`, `https://`, `ws://` and `wss://` URLs.
Eric Roman5ee3be22019-05-23 17:09:27112
113Communication to HTTP proxy servers is insecure, meaning proxied `http://`
114requests are sent in the clear. When proxying `https://` requests through an
115HTTP proxy, the TLS exchange is forwarded through the proxy using the `CONNECT`
116method, so end-to-end encryption is not broken. However when establishing the
117tunnel, the hostname of the target URL is sent to the proxy server in the
118clear.
119
120HTTP proxies in Chrome support the same HTTP authentiation schemes as for
Eric Roman12667032019-06-03 18:38:19121target servers: Basic, Digest, Negotiate, NTLM.
Eric Roman5ee3be22019-05-23 17:09:27122
123### HTTPS proxy scheme
124
125* Default port: 443
126* Example identifier (PAC): `HTTPS proxy:8080`
127* Example identifier (URI): `https://proxy:8080`
128
Eric Roman12667032019-06-03 18:38:19129This works like an [HTTP proxy](#HTTP-proxy-scheme), except the
130communication to the proxy server is protected by TLS, and may negotiate
Eric Roman77bc14c2019-06-05 20:40:52131HTTP/2 (but not QUIC).
Eric Roman5ee3be22019-05-23 17:09:27132
Eric Roman12667032019-06-03 18:38:19133Because the connection to the proxy server is secure, https:// requests
134sent through the proxy are not sent in the clear as with an HTTP proxy.
135Similarly, since CONNECT requests are sent over a protected channel, the
136hostnames for proxied https:// URLs is also not revealed.
137
138In addition to the usual HTTP authentication methods, HTTPS proxies also
139support client certificates.
140
141HTTPS proxies using HTTP/2 can offer better performance in Chrome than a
142regular HTTP proxy due to higher connection limits (HTTP/1.1 proxies in Chrome
143are limited to 32 simultaneous connections across all domains).
Eric Roman5ee3be22019-05-23 17:09:27144
Eric Romanc4abf6ca2019-06-06 21:29:20145Chrome, Firefox, and Opera support HTTPS proxies; however, most older HTTP
146stacks do not.
147
148Specifying an HTTPS proxy is generally not possible through system proxy
149settings. Instead, one must use either a PAC script or a Chrome proxy setting
150(command line, extension, or policy).
151
152See the dev.chromium.org document on [secure web
153proxies](http://dev.chromium.org/developers/design-documents/secure-web-proxy)
154for tips on how to run and test against an HTTPS proxy.
155
Eric Roman5ee3be22019-05-23 17:09:27156### SOCKSv4 proxy scheme
157
158* Default port: 1080
159* Example identifiers (PAC): `SOCKS4 proxy:8080`, `SOCKS proxy:8080`
160* Example identifier (URI): `socks4://proxy:8080`
161
162SOCKSv4 is a simple transport layer proxy that wraps a TCP socket. Its use
163is transparent to the rest of the protocol stack; after an initial
164handshake when connecting the TCP socket (to the proxy), the rest of the
165loading stack is unchanged.
166
167No proxy authentication methods are supported for SOCKSv4.
168
169When using a SOCKSv4 proxy, name resolution for target hosts is always done
170client side, and moreover must resolve to an IPv4 address (SOCKSv4 encodes
171target address as 4 octets, so IPv6 targets are not possible).
172
173There are extensions to SOCKSv4 that allow for proxy side name resolution, and
174IPv6, namely SOCKSv4a. However Chrome does not allow configuring, or falling
175back to v4a.
176
177A better alternative is to just use the newer version of the protocol, SOCKSv5
178(which is still 20+ years old).
179
180### SOCKSv5 proxy scheme
181
182* Default port: 1080
183* Example identifier (PAC): `SOCKS5 proxy:8080`
184* Example identifiers (URI): `socks://proxy:8080`, `socks5://proxy:8080`
185
186[SOCKSv5](https://tools.ietf.org/html/rfc1928) is a transport layer proxy that
187wraps a TCP socket, and allows for name resolution to be deferred to the proxy.
188
189In Chrome when a proxy's scheme is set to SOCKSv5, name resolution is always
190done proxy side (even though the protocol allows for client side as well). In
191Firefox client side vs proxy side name resolution can be configured with
192`network.proxy.socks_remote_dns`; Chrome has no equivalent option and will
193always use proxy side resolution.
194
195No authentication methods are supported for SOCKSv5 in Chrome (although some do
196exist for the protocol).
197
198A handy way to create a SOCKSv5 proxy is with `ssh -D`, which can be used to
199tunnel web traffic to a remote host over SSH.
200
201In Chrome SOCKSv5 is only used to proxy TCP-based URL requests. It cannot be
202used to relay UDP traffic.
203
Eric Romana11e367d2019-05-24 22:08:34204## Manual proxy settings
205
206The simplest way to configure proxy resolution is by providing a static list of
207rules comprised of:
208
Eric Roman12667032019-06-03 18:38:192091. A mapping of URL schemes to [proxy server identifiers](#Proxy-server-identifiers).
2102. A list of [proxy bypass rules](#Proxy-bypass-rules)
Eric Romana11e367d2019-05-24 22:08:34211
212We refer to this mode of configuration as "manual proxy settings".
213
214Manual proxy settings can succinctly describe setups like:
215
Eric Roman12667032019-06-03 18:38:19216* Use proxy `http://foo:8080` for all requests
217* Use proxy `http://foo:8080` for all requests except those to a `google.com`
Eric Romana11e367d2019-05-24 22:08:34218 subdomain.
Eric Roman12667032019-06-03 18:38:19219* Use proxy `http://foo:8080` for all `https://` requests, and proxy
220 `socsk5://mysocks:90` for everything else
Eric Romana11e367d2019-05-24 22:08:34221
222Although manual proxy settings are a ubiquituous way to configure proxies
223across platforms, there is no standard representation or feature set.
224
225Chrome's manual proxy settings most closely resembles that of WinInet. But it
226also supports idioms from other platforms -- for instance KDE's notion of
227reversing the bypass list, or Gnome's interpretation of bypass patterns as
228suffix matches.
229
230When defining manual proxy settings in Chrome, we specify three (possibly
Eric Roman12667032019-06-03 18:38:19231empty) lists of [proxy server identifiers](#Proxy-server-identifiers).
Eric Romana11e367d2019-05-24 22:08:34232
Eric Roman12667032019-06-03 18:38:19233 * proxies for HTTP - A list of proxy server identifiers to use for `http://`
234 requests, if non-empty.
235 * proxies for HTTPS - A list of proxy server identifiers to use for
236 `https://` requests, if non-empty.
237 * other proxies - A list of proxy server identifiers to use for everything
238 else (whatever isn't matched by the other two lists)
Eric Romana11e367d2019-05-24 22:08:34239
240There are a lot of ways to end up with manual proxy settings in Chrome
241(discussed in other sections).
242
243The following examples will use the command line method. Launching Chrome with
244`--proxy-server=XXX` (and optionally `--proxy-bypass-list=YYY`)
245
Eric Roman12667032019-06-03 18:38:19246Example: To use proxy `http://foo:8080` for all requests we can launch
247Chrome with `--proxy-server="http://foo:8080"`. This translates to:
Eric Romana11e367d2019-05-24 22:08:34248
249 * proxies for HTTP - *empty*
250 * proxies for HTTPS - *empty*
251 * other proxies - `http://foo:8080`
252
253With the above configuration, if the proxy server was unreachable all requests
254would fail with `ERR_PROXY_CONNECTION_FAILED`. To address this we could add a
255fallback to `DIRECT` by launching using
256`--proxy-server="http://foo:8080,direct://"` (note the comma separated list).
257This command line means:
258
259 * proxies for HTTP - *empty*
260 * proxies for HTTPS - *empty*
261 * other proxies - `http://foo:8080`, `direct://`
262
263If instead we wanted to proxy only `http://` URLs through the
Eric Roman12667032019-06-03 18:38:19264HTTPS proxy `https://foo:443`, and have everything else use the SOCKSv5 proxy
265`socks5://mysocks:1080` we could launch Chrome with
Eric Romana11e367d2019-05-24 22:08:34266`--proxy-server="http=https://foo:443;socks=socks5://mysocks:1080"`. This now
267expands to:
268
269 * proxies for HTTP - `https://foo:443`
270 * proxies for HTTPS - *empty*
271 * other proxies - `socks5://mysocks:1080`
272
Eric Roman12667032019-06-03 18:38:19273The command line above uses WinInet's proxy map format, with some additional
274features:
Eric Romana11e367d2019-05-24 22:08:34275
Eric Roman12667032019-06-03 18:38:19276* Instead of naming proxy servers by just a hostname:port, you can use Chrome's
277 URI format for proxy server identifiers. In other words, you can prefix the
278 proxy scheme so it doesn't default to HTTP.
279* The `socks=` mapping is understood more broadly as "other proxies". The
280 subsequent proxy list can include proxies of any scheme, however if the
281 scheme is omitted it will be understood as SOCKSv4 rather than HTTP.
Eric Romana11e367d2019-05-24 22:08:34282
Eric Roman12667032019-06-03 18:38:19283### Mapping WebSockets URLs to a proxy
Eric Romana11e367d2019-05-24 22:08:34284
Eric Roman12667032019-06-03 18:38:19285[Manual proxy settings](#Manual-proxy-settings) don't have mappings for `ws://`
286or `wss://` URLs.
Eric Romana11e367d2019-05-24 22:08:34287
288Selecting a proxy for these URL schemes is a bit different from other URL
289schemes. The algorithm that Chrome uses is:
290
291* If "other proxies" is non-empty use it
292* If "proxies for HTTPS" is non-empty use it
293* Otherwise use "proxies for HTTP"
294
295This is per the recommendation in section 4.1.3 of [RFC
2966455](https://tools.ietf.org/html/rfc6455).
297
298It is possible to route `ws://` and `wss://` separately using a PAC script.
299
Eric Roman12667032019-06-03 18:38:19300### Proxy credentials in manual proxy settings
Eric Romana11e367d2019-05-24 22:08:34301
Eric Roman12667032019-06-03 18:38:19302Most platforms' [manual proxy settings](#Manual-proxy-settings) allow
303specifying a cleartext username/password for proxy sign in. Chrome does not
304implement this, and will not use any credentials embedded in the proxy
305settings.
Eric Romana11e367d2019-05-24 22:08:34306
307Proxy authentication will instead go through the ordinary flow to find
308credentials.
309
310## Proxy bypass rules
311
Eric Roman12667032019-06-03 18:38:19312In addition to specifying three lists of [proxy server
313identifiers](#proxy-server-identifiers), Chrome's [manual proxy
314settings](#Manual-proxy-settings) lets you specify a list of "proxy bypass
315rules".
Eric Romana11e367d2019-05-24 22:08:34316
317This ruleset determines whether a given URL should skip use of a proxy all
318together, even when a proxy is otherwise defined for it.
319
320This concept is also known by names like "exception list", "exclusion list" or
321"no proxy list".
322
323Proxy bypass rules can be written as an ordered list of strings. Ordering
324generally doesn't matter, but may when using subtractive rules.
325
326When manual proxy settings are specified from the command line, the
327`--proxy-bypass-list="RULES"` switch can be used, where `RULES` is a semicolon
328or comma separated list of bypass rules.
329
330Following are the string constructions for the bypass rules that Chrome
331supports. They can be used when defining a Chrome manual proxy settings from
332command line flags, extensions, or policy.
333
334When using system proxy settings, one should use the platform's rule format and
335not Chrome's.
336
337### Bypass rule: Hostname
338
339```
340[ URL_SCHEME "://" ] HOSTNAME_PATTERN [ ":" <port> ]
341```
342
343Matches a hostname using a wildcard pattern, and an optional scheme and port
344restriction.
345
346Examples:
347
348* `foobar.com` - Matches URL of any scheme and port, whose normalized host is
349 `foobar.com`
350* `*foobar.com` - Matches URL of any scheme and port, whose normalized host
351 ends with `foobar.com` (for instance `blahfoobar.com` and `foo.foobar.com`).
352* `*.org:443` - Matches URLs of any scheme, using port 443 and whose top level
353 domain is `.org`
354* `https://x.*.y.com:99` - Matches https:// URLs on port 99 whose normalized
355 hostname matches `x.*.y.com`
356
357### Bypass rule: Subdomain
358
359```
360[ URL_SCHEME "://" ] "." HOSTNAME_SUFFIX_PATTERN [ ":" PORT ]
361```
362
363Hostname patterns that start with a dot are special cased to mean a subdomain
364matches. `.foo.com` is effectively another way of writing `*.foo.com`.
365
366Examples:
367
368* `.google.com` - Matches `calendar.google.com` and `foo.bar.google.com`, but
369 not `google.com`.
370* `http://.google.com` - Matches only http:// URLs that are a subdomain of `google.com`.
371
372### Bypass rule: IP literal
373
374```
375[ SCHEME "://" ] IP_LITERAL [ ":" PORT ]
376```
377
378Matches URLs that are IP address literals, and optional scheme and port
379restrictions. This is a special case of hostname matching that takes into
380account IP literal canonicalization. For example the rules `[0:0:0::1]` and
381`[::1]` are equivalent (both represent the same IPv6 address).
382
383Examples:
384
385* `127.0.0.1`
386* `http://127.0.0.1`
387* `[::1]` - Matches any URL to the IPv6 loopback address.
388* `[0:0::1]` - Same as above
389* `http://[::1]:99` - Matches any http:// URL to the IPv6 loopback on port 99
390
391### Bypass rule: IPv4 address range
392
393```
394IPV4_LITERAL "/" PREFIX_LENGTH_IN_BITS
395```
396
397Matches any URL whose hostname is an IPv4 literal, and falls between the given
398address range.
399
Eric Roman12667032019-06-03 18:38:19400Note this [only applies to URLs that are IP
401literals](#Meaning-of-IP-address-range-bypass-rules).
Eric Romana11e367d2019-05-24 22:08:34402
403Examples:
404
405* `192.168.1.1/16`
406
407### Bypass rule: IPv6 address range
408
409```
410IPV6_LITERAL "/" PREFIX_LENGTH_IN_BITS
411```
412
413Matches any URL that is an IPv6 literal that falls between the given range.
414Note that IPv6 literals must *not* be bracketed.
415
Eric Roman12667032019-06-03 18:38:19416Note this [only applies to URLs that are IP
417literals](#Meaning-of-IP-address-range-bypass-rules).
Eric Romana11e367d2019-05-24 22:08:34418
419Examples:
420
421* `fefe:13::abc/33`
422* `[fefe::]/40` -- WRONG! IPv6 literals must not be bracketed.
423
424### Bypass rule: Simple hostnames
425
426```
427<local>
428```
429
430Matches hostnames without a period in them, and that are not IP literals. This
431is a naive string search -- meaning that periods appearing *anywhere* count
432(including trailing dots!).
433
434This rule corresponds to the "Exclude simple hostnames" checkbox on macOS and
435the "Don't use proxy server for local (intranet) addresses" on Windows.
436
437The rule name comes from WinInet, and can easily be confused with the concept
438of localhost. However the two concepts are completely orthogonal. In practice
Eric Roman12667032019-06-03 18:38:19439one wouldn't add rules to bypass localhost, as it is [already done
440implicitly](#Implicit-bypass-rules).
Eric Romana11e367d2019-05-24 22:08:34441
442### Bypass rule: Subtract implicit rules
443
444```
445<-loopback>
446```
447
Eric Roman12667032019-06-03 18:38:19448*Subtracts* the [implicit proxy bypass rules](#Implicit-bypass-rules)
449(localhost and link local addresses). This is generally only needed for test
David Benjamin2cbca1a2020-11-09 23:41:36450setups. Beware of the security implications to proxying localhost.
Eric Romana11e367d2019-05-24 22:08:34451
452Whereas regular bypass rules instruct the browser about URLs that should *not*
453use the proxy, this rule has the opposite effect and tells the browser to
454instead *use* the proxy.
455
456Ordering may matter when using a subtractive rule, as rules will be evaluated
457in a left-to-right order. `<-loopback>;127.0.0.1` has a subtly different effect
458than `127.0.0.1;<-loopback>`.
459
460### Meaning of IP address range bypass rules
461
Eric Roman12667032019-06-03 18:38:19462The IP address range bypass rules in manual proxy settings applies only to URL
463literals. This is not what one would intuitively expect.
Eric Romana11e367d2019-05-24 22:08:34464
465Example:
466
467Say we have have configured a proxy for all requests, but added a bypass rule
468for `192.168.0.0.1/16`. If we now navigate to `http://foo` (which resolves
469to `192.168.1.5` in our setup) will the browser connect directly (bypass proxy)
470because we have indicated a bypass rule that includes this IP?
471
472It will go through the proxy.
473
474The bypass rule in this case is not applicable, since the browser never
475actually does a name resolution for `foo`. Proxy resolution happens before
476name resolution, and depending on what proxy scheme is subsequently chosen,
477client side name resolution may never be performed.
478
479The usefulness of IP range proxy bypass rules is rather limited, as they only
480apply to requests whose URL was explicitly an IP literal.
481
482If proxy decisions need to be made based on the resolved IP address(es) of a
483URL's hostname, one must use a PAC script.
484
Eric Roman591bb0d2019-05-02 20:57:17485## Implicit bypass rules
486
Eric Roman65019bb2019-05-03 20:56:15487Requests to certain hosts will not be sent through a proxy, and will instead be
488sent directly.
Eric Roman591bb0d2019-05-02 20:57:17489
490We call these the _implicit bypass rules_. The implicit bypass rules match URLs
491whose host portion is either a localhost name or a link-local IP literal.
492Essentially it matches:
493
494```
495localhost
496*.localhost
497[::1]
498127.0.0.1/8
499169.254/16
500[FE80::]/10
501```
502
503The complete rules are slightly more complicated. For instance on
Frédéric Wang71698e62020-12-10 06:13:52504Windows we will also recognize `loopback`.
Eric Roman591bb0d2019-05-02 20:57:17505
506This concept of implicit proxy bypass rules is consistent with the
507platform-level proxy support on Windows and macOS (albeit with some differences
508due to their implementation quirks - see compatibility notes in
509`net::ProxyBypassRules::MatchesImplicitRules`)
510
511Why apply implicit proxy bypass rules in the first place? Certainly there are
512considerations around ergonomics and user expectation, but the bigger problem
513is security. Since the web platform treats `localhost` as a secure origin, the
514ability to proxy it grants extra powers. This is [especially
515problematic](https://bugs.chromium.org/p/chromium/issues/detail?id=899126) when
516proxy settings are externally controllable, as when using PAC scripts.
517
518Historical support in Chrome:
519
Eric Roman3aa29ee2020-04-14 18:53:47520* Prior to M71 there were no implicit proxy bypass rules, except if using
521 [`--winhttp-proxy-resolver`](#winhttp_proxy_resolver-command-line-switch).
Eric Roman591bb0d2019-05-02 20:57:17522* In M71 Chrome applied implicit proxy bypass rules to PAC scripts
Eric Roman65019bb2019-05-03 20:56:15523* In M72 Chrome generalized the implicit proxy bypass rules to manually
524 configured proxies
Eric Roman591bb0d2019-05-02 20:57:17525
Eric Roman12667032019-06-03 18:38:19526### Overriding the implicit bypass rules
Eric Roman591bb0d2019-05-02 20:57:17527
528If you want traffic to `localhost` to be sent through a proxy despite the
529security concerns, it can be done by adding the special proxy bypass rule
530`<-loopback>`. This has the effect of _subtracting_ the implicit rules.
531
532For instance, launch Chrome with the command line flag:
533
534```
535--proxy-bypass-list="<-loopback>"
536```
537
538Note that there currently is no mechanism to disable the implicit proxy bypass
539rules when using a PAC script. Proxy bypass lists only apply to manual
540settings, so the technique above cannot be used to let PAC scripts decide the
541proxy for localhost URLs.
Eric Roman1c751362019-05-03 16:56:39542
543## Evaluating proxy lists (proxy fallback)
544
Eric Roman12667032019-06-03 18:38:19545Proxy resolution results in a _list_ of [proxy server
546identifiers](#Proxy-server-identifiers) to use for a
547given request, not just a single proxy server identifier.
Eric Roman1c751362019-05-03 16:56:39548
549For instance, consider this PAC script:
550
551```
552function FindProxyForURL(url, host) {
553 if (host == "www.example.com") {
554 return "PROXY proxy1; HTTPS proxy2; SOCKS5 proxy3";
555 }
556 return "DIRECT";
557}
558
559```
560
561What proxy will Chrome use for connections to `www.example.com`, given that
Eric Roman12667032019-06-03 18:38:19562we have a choice of three separate proxy server identifiers to choose from
563{`http://proxy1:80`, `https://proxy2:443`, `socks5://proxy3:1080`}?
Eric Roman1c751362019-05-03 16:56:39564
Eric Roman12667032019-06-03 18:38:19565Initially, Chrome will try the proxies in order. This means first attempting
566the request through `http://proxy1:80`. If that "fails", the request is
567next attempted through `https://proxy2:443`. Lastly if that fails, the
568request is attempted through `socks5://proxy3:1080`.
Eric Roman1c751362019-05-03 16:56:39569
570This process is referred to as _proxy fallback_. What constitutes a
571"failure" is described later.
572
573Proxy fallback is stateful. The actual order of proxy attempts made be Chrome
574is influenced by the past responsiveness of proxy servers.
575
Eric Roman65019bb2019-05-03 20:56:15576Let's say we request `http://www.example.com/`. Per the PAC script this
Eric Roman12667032019-06-03 18:38:19577resolves to a list of three proxy server identifiers:
Eric Roman1c751362019-05-03 16:56:39578
Eric Roman12667032019-06-03 18:38:19579{`http://proxy1:80`, `https://proxy2:443`, `socks5://proxy3:1080`}
Eric Roman1c751362019-05-03 16:56:39580
581Chrome will first attempt to issue the request through these proxies in the
Eric Roman12667032019-06-03 18:38:19582left-to-right order.
Eric Roman1c751362019-05-03 16:56:39583
Eric Roman12667032019-06-03 18:38:19584Let's say that the attempt through `http://proxy1:80` fails, but then the
585attempt through `https://proxy2:443` succeeds. Chrome will mark
586`http://proxy1:80` as _bad_ for the next 5 minutes. Being marked as _bad_
587means that `http://proxy1:80` is de-prioritized with respect to
588other proxy server identifiers (including `direct://`) that are not marked as
589bad.
Eric Roman1c751362019-05-03 16:56:39590
591That means the next time `http://www.example.com/` is requested, the effective
592order for proxies to attempt will be:
593
Eric Roman12667032019-06-03 18:38:19594{`https://proxy2:443`, `socks5://proxy3:1080`, `http://proxy1:80`}
Eric Roman1c751362019-05-03 16:56:39595
596Conceptually, _bad_ proxies are moved to the end of the list, rather than being
597removed from consideration all together.
598
599What constitutes a "failure" when it comes to triggering proxy fallback depends
600on the proxy type. Generally speaking, only connection level failures
601are deemed eligible for proxy fallback. This includes:
602
603* Failure resolving the proxy server's DNS
604* Failure connecting a TCP socket to the proxy server
605
606(There are some caveats for how HTTPS and QUIC proxies count failures for
607fallback)
608
609Prior to M67, Chrome would consider failures establishing a
610CONNECT tunnel as an error eligible for proxy fallback. This policy [resulted
611in problems](https://bugs.chromium.org/p/chromium/issues/detail?id=680837) for
612deployments whose HTTP proxies intentionally failed certain https:// requests,
613since that necessitates inducing a failure during the CONNECT tunnel
614establishment. The problem would occur when a working proxy fallback option
615like DIRECT was given, since the failing proxy would then be marked as bad.
616
617Currently there are no options to configure proxy fallback (including disabling
618the caching of bad proxies). Future versions of Chrome may [remove caching
619of bad proxies](https://bugs.chromium.org/p/chromium/issues/detail?id=936130)
620to make fallback predictable.
621
622To investigate issues relating to proxy fallback, one can [collect a NetLog
623dump using
624chrome://net-export/](https://dev.chromium.org/for-testers/providing-network-details).
625These logs can then be loaded with the [NetLog
626viewer](https://netlog-viewer.appspot.com/).
627
628There are a few things of interest in the logs:
629
630* The "Proxy" tab will show which proxies (if any) were marked as bad at the
631 time the capture ended.
632* The "Events" tab notes what the resolved proxy list was, and what the
633 re-ordered proxy list was after taking into account bad proxies.
634* The "Events" tab notes when a proxy is marked as bad and why (provided the
635 event occurred while capturing was enabled).
636
637When debugging issues with bad proxies, it is also useful to reset Chrome's
638cache of bad proxies. This can be done by clicking the "Clear bad proxies"
639button on
640[chrome://net-internals/#proxy](chrome://net-internals/#proxy). Note the UI
641will not give feedback that the bad proxies were cleared, however capturing a
642new NetLog dump can confirm it was cleared.
Eric Roman65019bb2019-05-03 20:56:15643
Eric Roman12667032019-06-03 18:38:19644## Arguments passed to FindProxyForURL() in PAC scripts
Eric Roman65019bb2019-05-03 20:56:15645
646PAC scripts in Chrome are expected to define a JavaScript function
647`FindProxyForURL`.
648
649The historical signature for this function is:
650
651```
652function FindProxyForURL(url, host) {
653 ...
654}
655```
656
657Scripts can expect to be called with string arguments `url` and `host` such
658that:
659
660* `url` is a *sanitized* version of the request's URL
661* `host` is the unbracketed host portion of the origin.
662
663Sanitization of the URL means that the path, query, fragment, and identity
664portions of the URL are stripped. Effectively `url` will be
665limited to a `scheme://host:port/` style URL
666
667Examples of how `FindProxyForURL()` will be called:
668
669```
670// Actual URL: https://www.google.com/Foo
671FindProxyForURL('https://www.google.com/', 'www.google.com')
672
673// Actual URL: https://[dead::beef]/foo?bar
674FindProxyForURL('https://[dead::beef]/', 'dead::beef')
675
676// Actual URL: https://www.example.com:8080#search
677FindProxyForURL('https://www.example.com:8080/', 'example.com')
678
679// Actual URL: https://username:[email protected]
680FindProxyForURL('https://www.example.com/', 'example.com')
681```
682
683Stripping the path and query from the `url` is a departure from the original
684Netscape implementation of PAC. It was introduced in Chrome 52 for [security
685reasons](https://bugs.chromium.org/p/chromium/issues/detail?id=593759).
686
687There is currently no option to turn off sanitization of URLs passed to PAC
688scripts (removed in Chrome 75).
689
690The sanitization of http:// URLs currently has a different policy, and does not
691strip query and path portions of the URL. That said, users are advised not to
692depend on reading the query/path portion of any URL
693type, since future versions of Chrome may [deprecate that
694capability](https://bugs.chromium.org/p/chromium/issues/detail?id=882536) in
695favor of a consistent policy.
Eric Roman09fd4ce52019-05-16 21:55:39696
Eric Roman12667032019-06-03 18:38:19697## Resolving client's IP address within a PAC script using myIpAddress()
Eric Roman09fd4ce52019-05-16 21:55:39698
699PAC scripts can invoke `myIpAddress()` to obtain the client's IP address. This
700function returns a single IP literal, or `"127.0.0.1"` on failure.
701
Eric Roman649985b2020-04-29 20:43:02702This API is [inherently ambiguous when used on multi-homed
703hosts](#myIpAddress_myIpAddressEx_and-multi_homed-hosts), as such hosts can
704have multiple IP addresses and yet the browser can pick just one to return.
Eric Roman09fd4ce52019-05-16 21:55:39705
Eric Roman649985b2020-04-29 20:43:02706Chrome's algorithm for `myIpAddress()` favors returning the IP that would be
707used if we were to connect to the public internet, by executing the following
708ordered steps and short-circuiting once the first candidate IP is found:
Eric Roman09fd4ce52019-05-16 21:55:39709
7101. Select the IP of an interface that can route to public Internet:
711 * Probe for route to `8.8.8.8`.
712 * Probe for route to `2001:4860:4860::8888`.
7132. Select an IP by doing a DNS resolve of the machine's hostname:
714 * Select the first IPv4 result if there is one.
715 * Select the first IP result if there is one.
7163. Select the IP of an interface that can route to private IP space:
717 * Probe for route to `10.0.0.0`.
718 * Probe for route to `172.16.0.0`.
719 * Probe for route to `192.168.0.0`.
720 * Probe for route to `FC00::`.
721
Eric Roman649985b2020-04-29 20:43:02722Note that when searching for candidate IP addresses, link-local and loopback
723addresses are skipped over. Link-local or loopback address will only be returned as a
Eric Roman09fd4ce52019-05-16 21:55:39724last resort when no other IP address was found by following these steps.
725
Eric Roman649985b2020-04-29 20:43:02726This sequence of steps explicitly favors IPv4 over IPv6 results, to match
727Internet Explorer's IPv6 support.
Eric Romana36bff3b2019-05-17 18:11:58728
729*Historical note*: Prior to M72, Chrome's implementation of `myIpAddress()` was
730effectively just `getaddrinfo(gethostname)`. This is now step 2 of the heuristic.
731
Eric Roman12667032019-06-03 18:38:19732## Resolving client's IP address within a PAC script using myIpAddressEx()
Eric Roman09fd4ce52019-05-16 21:55:39733
Eric Romanac586882019-05-17 18:59:08734Chrome supports the [Microsoft PAC
735extension](https://docs.microsoft.com/en-us/windows/desktop/winhttp/myipaddressex)
736`myIpAddressEx()`.
737
738This is like `myIpAddress()`, but instead of returning a single IP address, it
739can return multiple IP addresses. It returns a string containing a semi-colon
740separated list of addresses. On failure it returns an empty string to indicate
741no results (whereas `myIpAddress()` returns `127.0.0.1`).
742
743There are some differences with Chrome's implementation:
744
745* In Chrome the function is unconditionally defined, whereas in Internet
746 Explorer one must have used the `FindProxyForURLEx` entrypoint.
Eric Roman649985b2020-04-29 20:43:02747* Chrome [does not necessarily enumerate all of the host's network
748 interfaces](#myIpAddress_myIpAddressEx_and-multi_homed-hosts)
Eric Romanac586882019-05-17 18:59:08749* Chrome does not return link-local or loopback addresses (except if no other
750 addresses were found).
751
752The algorithm that Chrome uses is nearly identical to that of `myIpAddress()`
Eric Roman649985b2020-04-29 20:43:02753described earlier, but in certain cases may return multiple IPs.
Eric Romanac586882019-05-17 18:59:08754
7551. Select all the IPs of interfaces that can route to public Internet:
756 * Probe for route to `8.8.8.8`.
757 * Probe for route to `2001:4860:4860::8888`.
758 * If any IPs were found, return them, and finish.
7592. Select an IP by doing a DNS resolve of the machine's hostname:
760 * If any IPs were found, return them, and finish.
7613. Select the IP of an interface that can route to private IP space:
762 * Probe for route to `10.0.0.0`.
763 * Probe for route to `172.16.0.0`.
764 * Probe for route to `192.168.0.0`.
765 * Probe for route to `FC00::`.
766 * If any IPs were found, return them, and finish.
767
768Note that short-circuiting happens whenever steps 1-3 find a candidate IP. So
769for example if at least one IP address was discovered by checking routes to
770public Internet, only those IPs will be returned, and steps 2-3 will not run.
Eric Romanc5816ebb2019-11-13 18:08:46771
Eric Roman649985b2020-04-29 20:43:02772## myIpAddress() / myIpAddressEx() and multi-homed hosts
773
774`myIpAddress()` is a poor API for hosts that have multiple IP addresses, as it
775can only return a single IP, which may or may not be the one you wanted. Both
776`myIpAddress()` and `myIpAddressEx()` favor returning the IP for the interface
777that would be used to route to the public internet.
778
779As an API, `myIpAddressEx()` offers more flexibility since it can return
780multiple IP addresses. However Chrome's implementation restricts which IPs a
781PAC script can see [due to privacy
782concerns](https://bugs.chromium.org/p/chromium/issues/detail?id=905366). So
783using `myIpAddressEx()` is not as powerful as enumerating all the host's IPs,
784and may not address all use-cases.
785
786A more reliable strategy for PAC scripts to check which network(s) a user is on
787is to probe test domains using `dnsResolve()` / `dnsResolveEx()`.
788
789Moreover, note that Chrome does not support the Firefox-specific
790`pacUseMultihomedDNS` option, so adding that global to a PAC script has no
791special side-effect in Chrome. Whereas in Firefox it reconfigures
792`myIpAddress()` to be dependent on the target URL that `FindProxyForURL()` was
793called with.
794
Eric Romanc5816ebb2019-11-13 18:08:46795## Android quirks
796
797Proxy resolving via PAC works differently on Android than other desktop Chrome
798platforms:
799
800* Android Chrome uses the same Chromium PAC resolver, however does not run it
801 out-of-process as on Desktop Chrome. This architectural difference is
802 due to the higher process cost on Android, and means Android Chrome is more
803 susceptible to malicious PAC scripts. The other consequence is that Android
804 Chrome can have distinct regressions from Desktop Chrome as the service setup
805 is quite different (and most `browser_tests` are not run on Android either).
806
807* [WebView does not use Chrome's PAC
808 resolver](https://bugs.chromium.org/p/chromium/issues/detail?id=989667).
809 Instead Android WebView uses the Android system's PAC resolver, which is less
810 optimized and uses an old build of V8. When the system is configured to use
811 PAC, Android WebView's net code will see the proxy settings as being a
812 single HTTP proxy on `localhost`. The system localhost proxy will in turn
813 evaluate the PAC script and forward the HTTP request on to the resolved
814 proxy. This translation has a number of effects, including what proxy
815 schemes are supported, the maximum connection limits, how proxy fallback
816 works, and overall performance (the current Android PAC evaluator blocks on
817 DNS).
818
819* Android system log messages for `PacProcessor` are not related to Chrome or
820 its PAC evaluator. Rather, these are log messages generated by the Android
821 system's PAC implementation. This confusion can arise when users add
822 `alert()` to debug PAC script logic, and then refer to output in `logcat` to
823 try and diagnose a resolving issue in Android Chrome.
Eric Roman0fdcd4f12020-03-03 22:22:03824
825## Downloading PAC scripts
826
827When a network context is configured to use a PAC script, proxy resolution will
828stall while downloading the PAC script.
829
830Fetches for PAC URLs are initiated by the network stack, and behave differently
831from ordinary web visible requests:
832
833* Must complete within 30 seconds.
834* Must complete with an HTTP response code of exactly 200.
835* Must have an uncompressed body smaller than 1 MB.
836* Do not follow ordinary HTTP caching semantics.
837* Are never fetched through a proxy
838* Are not visible to the WebRequest extension API, or to service workers.
839* Do not support HTTP authentication (ambient authentication may work, but
840 cannot prompt UI for credentials).
841* Do not support client certificates (including `AutoSelectCertificateForUrls`)
842* Do not support auxiliary certificate network fetches (will only used cached
843 OCSP, AIA, and CRL responses during certificate verification).
844
845### Caching of successful PAC fetches
846
847PAC URLs are always fetched from the network, and never from the HTTP cache.
848After a PAC URL is successfully fetched, its contents (which are used to create
849a long-lived Java Script context) will be assumed to be fresh until either:
850
851* The network changes (IP address changes, DNS configuration changes)
852* The response becomes older than 12 hours
853* A user explicitly invalidates PAC through `chrome://net-internals#proxy`
854
855Once considered stale, the PAC URL will be re-fetched the next time proxy
856resolution is requested.
857
858### Fallback for failed PAC fetches
859
860When the proxy settings are configured to use a PAC URL, and that PAC URL
861cannot be fetched, proxy resolution will fallback to the next option, which is
862often `DIRECT`:
863
864* If using system proxy settings, and the platform supports fallback to manual
865 proxy settings (e.g. Windows), the specified manual proxy servers will be
866 used after the PAC fetch fails.
867* If using Chrome's proxy settings, and the PAC script was marked as
868 [mandatory](https://developer.chrome.com/extensions/proxy), fallback to
869 `DIRECT` is not permitted. Subsequent network requests will fail proxy
870 resolution and complete with `ERR_MANDATORY_PROXY_CONFIGURATION_FAILED`.
871* Otherwise proxy resolution will silently fall back to `DIRECT`.
872
873### Recovering from failed PAC fetches
874
875When fetching an explicitly configured PAC URL fails, the browser will try to
876re-fetch it:
877
878* In exactly 8 seconds
879* 32 seconds after that
880* 2 minutes after that
881* Every 4 hours thereafter
882
883This background polling of the PAC URL is only initiated in response to an
884incoming proxy resolution request, so it will not trigger work when the browser
885is otherwise idle.
886
887Similarly to successful fetches, the PAC URL will be also be re-fetched
888whenever the network changes, the proxy settings change, or it was manually
889invalidated via `chrome://net-internals#proxy`.
890
891### Text encoding
892
893Note that UTF-8 is *not* the default interpretation of PAC response bodies.
894
895The priority for encoding is determined in this order:
896
8971. The `charset` property of the HTTP response's `Content-Type`
8982. Any BOM at the start of response body
8993. Otherwise defaults to ISO-8859-1.
900
901When setting the `Content-Type`, servers should prefer using a mime type of
902`application/x-ns-proxy-autoconfig` or `application/x-javascript-config`.
903However in practice, Chrome does not enforce the mime type.
Eric Roman29a49f82020-04-09 17:34:23904
905## Capturing a Net Log for debugging proxy resolution issues
906
907Issues in proxy resolution are best investigated using a Net Log.
908
909A good starting point is to follow the [general instructions for
910net-export](https://www.chromium.org/for-testers/providing-network-details),
911*and while the Net Log is being captured perform these steps*:
912
9131. Reproduce the failure (ex: load a URL that fails)
9142. If you can reproduce a success, do so (ex: load a different URL that succeeds).
9153. In a new tab, navigate to `chrome://net-internals/#proxy` and click both
916 buttons ("Re-apply settings" and "Clear bad proxies").
9174. Repeat step (1)
9185. Stop the Net Log and save the file.
919
920The resulting Net Log should have enough information to diagnose common
921problems. It can be attached to a bug report, or explored using the [Net Log
922Viewer](https://netlog-viewer.appspot.com/). See the next section for some tips
923on analyzing it.
924
925## Analyzing Net Logs for proxy issues
926
927Load saved Net Logs using [Net Log Viewer](https://netlog-viewer.appspot.com/).
928
929### Proxy overview tab
930
931Start by getting a big-picture view of the proxy settings by clicking to the
932"Proxy" tab on the left. This summarizes the proxy settings at the time the
933_capture ended_.
934
935* Does the _original_ proxy settings match expectation?
936 The proxy settings might be coming from:
937 * Managed Chrome policy (chrome://policy)
938 * Command line flags (ex: `--proxy-server`)
939 * (per-profile) Chrome extensions (ex: [chrome.proxy](https://developer.chrome.com/extensions/proxy))
940 * (per-network) System proxy settings
941
Eric Roman21ea63d32020-04-13 18:01:00942* Was [proxy autodetect (WPAD)](#Web-Proxy-Auto_Discovery-WPAD) specified? In
943 this case the final URL probed will be reflected by the difference between
944 the "Effective" and "Original" settings.
Eric Roman29a49f82020-04-09 17:34:23945
946* Internally, proxy settings are per-NetworkContext. The proxy
947 overview tab shows settings for a *particular* NetworkContext, namely the
948 one associated with the Profile used to navigate to `chrome://net-export`. For
949 instance if the net-export was initiated from an Incognito window, it may
950 show different proxy settings here than a net-export capture initiated by a
951 non-Incognito window. When the net-export was triggered from command line
952 (`--log-net-log`) no particular NetworkContext is associated with the
953 capture and hence no proxy settings will be shown in this overview.
954
955* Were any proxies marked as bad?
956
957### Import tab
958
959Skim through the Import tab and look for relevant command line flags and active
960field trials. A find-in-page for `proxy` is a good starting point. Be on the lookout for
Eric Roman3aa29ee2020-04-14 18:53:47961[`--winhttp-proxy-resolver`](#winhttp_proxy_resolver-command-line-switch) which
962has [known problems](https://bugs.chromium.org/p/chromium/issues/detail?id=644030).
Eric Roman29a49f82020-04-09 17:34:23963
964### Events tab
965
966To deep dive into proxy resolution, switch to the Events tab.
967
968You can start by filtering on `type:URL_REQUEST` to see all the top level
969requests, and then keep click through the dependency links to
970trace the proxy resolution steps and outcome.
971
972The most relevant events have either `PROXY_`, `PAC_`, or
973`WPAD_` in their names. You can also try filtering for each of those.
974
975Documentation on specific events is available in
976[net_log_event_type_list.h](https://chromium.googlesource.com/chromium/src/+/HEAD/net/log/net_log_event_type_list.h).
977
978Network change events can also be key to understanding proxy issues. After
979switching networks (ex VPN), the effective proxy settings, as well as content
980of any PAC scripts/auto-detect can change.
Eric Romana953f0a42020-04-10 19:42:28981
982## Web Proxy Auto-Discovery (WPAD)
983
984When configured to use WPAD (aka "autotmaticaly detect proxy settings"), Chrome
985will prioritize:
986
9871. DHCP-based WPAD (option 252)
9882. DNS-based WPAD
989
990These are tried in order, however DHCP-based WPAD is only supported for Chrome
991on Windows and Chrome on Chrome OS.
992
993WPAD is the system default for many home and Enterprise users.
994
995### Chrome on macOS support for DHCP-based WPAD
996
997Chrome on macOS does not support DHCP-based WPAD when configured to use
998"autodetect".
999
1000However, macOS might perform DHCP-based WPAD and embed this discovered PAC URL
1001as part of the system proxy settings. So effectively when Chrome is configured
1002to "use system proxy settings" it may behave as if it supports DHCP-based WPAD.
1003
1004### Dangers of DNS-based WPAD and DNS search suffix list
1005
1006DNS-based WPAD involves probing for the non-FQDN `wpad`. This means
1007WPAD's performance and security is directly tied to the user's DNS search
1008suffix list.
1009
1010When resolving `wpad`, the host's DNS resolver will complete the hostname using
1011each of the suffixes in the search list:
1012
10131. If the suffix list is long this process can very slow, as it triggers a
1014 cascade of NXDOMAIN.
10152. If the suffix list includes domains *outside of the administrative domain*,
1016 WPAD may select an attacker controlled PAC server, and can subsequently
1017 funnel the user's traffic through a proxy server of their choice. The
1018 evolution of TLDs further increases this risk, since what were previously
1019 private suffixes used by an enterprise can become publicly registerable.
1020 See also [WPAD Name Collision
1021 Vulnerability](https://www.us-cert.gov/ncas/alerts/TA16-144A)
Eric Roman3aa29ee2020-04-14 18:53:471022
1023## --winhttp-proxy-resolver command line switch
1024
1025Passing the `--winhttp-proxy-resolver` command line argument instructs Chrome
1026to use the system libraries for *one narrow part of proxy resolution*: evaluating
1027a given PAC script.
1028
1029Use of this flag is NOT a supported mode, and has [known
1030problems](https://bugs.chromium.org/p/chromium/issues/detail?id=644030): It
1031can break Chrome extensions (`chrome.proxy` API), the interpretation of
1032Proxy policies, hurt performance, and doesn't ensure full fidelity
1033interpretation of system proxy settings.
1034
1035Another oddity of this switch is that it actually gets interpreted with a
1036smilar meaning on other platforms (macOS), despite its Windows-specific naming.
1037
1038This flag was historically exposed for debugging, and to mitigate unresolved
1039policy differences in PAC execution. In the future this switch [will be
1040removed](https://bugs.chromium.org/p/chromium/issues/detail?id=644030).
1041
1042Although Chrome would like full fidelity with Windows proxy settings, there are
1043limits to those integrations. Dependencies like NRPT for proxy
1044resolution necessitate using Windows proxy resolution libraries directly
1045instead of Chrome's. We hope these less common use cases will be fully
1046addressed by [this
1047feature](https://bugs.chromium.org/p/chromium/issues/detail?id=1032820)