Proxies, proxies everywhere but still no Internet

This post has been republished via RSS; it originally appeared at: Core Infrastructure and Security Blog articles.

Howdy everyone, a quick tangent from our regularly scheduled Introduction to Network Trace Analysis series to talk about the Windows Proxy ecosystem. A Windows Proxy configuration can be a little tricky, so I wanted to add clarity for configuration methods. Scoping things a bit here I will also only be referring to 64-bit applications.  


But first, let’s explain what I mean when I say proxy.  


What even is a proxy?


Simply, it is a device or software making a network request on the client's behalf. For clarity, we will only cover web request proxies or HTTP/HTTPS proxies.  


In the context of proxies in this article I will  NOT  be covering the  Web Application Proxy  or the  Microsoft Entra application proxy .  


There are a few proxy specific terms I would like to define before we jump into things:  


  • Static Proxy: This is a traditional proxy. All traffic that is not in the bypass-list is sent to the defined proxy server.  
  • Bypass-list: A list of endpoints that are excluded from the static proxy.  
  • Auto Configuration Proxy: This is a more dynamic proxy that allows the utilization of a proxy auto-configuration (PAC) file.  
  • Web Proxy Auto-Discovery (WPAD): This is a way to configure a proxy through DNS or DHCP  
    • WPAD is defined in a WPAD.dat file which is the same as a proxy.pac file in format.  
  • Auto Configuration URL: The URL location where the client will be requesting its proxy.pac from  
    • In this article I will be using the shorthand AutoConfig URL or ACU to refer to this URL.  


Why should I care?  


If you do not ever intend to use a proxy, then you can be done right here! This post is not an endorsement that your environment should be using a Windows proxy. But if you are using Windows proxies, or love learning like I do, I recommend you stick around anyway. You may think "If I misconfigure a proxy, I just won't be able to get to some websites", and while that technically may be true, those websites have varying degrees of criticality.   For example, if you block network traffic to  you will find that many Office products will fail with inability to sign in or be unable to verify their license. Or maybe you accidentally blocked a public CRL site and now your PKI infrastructure is very unhappy with you. Oops.  

As a quick reference, if you are curious about necessary endpoints for different Windows functionality this is a good starting point  Manage connection endpoints for Windows 11 Enterprise . Please be aware that this list is not exhaustive. So to say proxies are important may be an understatement.  


With all of this in mind, I am sure your next question is "How do I use a proxy?" to which I say, well... it depends on which one...  


Microsoft Windows HTTP Services (WinHTTP)  


Let's start with the WinHTTP proxy since it is the foundation on which the other proxies stand.  It is useful to think of WinHTTP in two parts. The WinHTTP API provider that allows developers to perform HTTP client work, and the WinHTTP Web Proxy Auto-Discovery Service (WinHttpAutoProxySvc).   


These two parts are related but are not the same. One of the WinHttpAutoProxySvcs responsibilities is to process the proxy.pac and WPAD.dat. Going forward in this blog post when I am referring to WinHTTP, it is in reference to the API not the service.  


WinHTTP  is a client API set intended for making web requests for server applications. Not to be confused with the  HTTP Server API  which is often incorrectly referred to as WinHTTP.  


Taking a second to zoom in on that second sentence “ … a client API set intended for making web requests for server applications.” .  


When I say server applications, I am referring to applications that run in a non-interactive way. A fitting example of this is the Windows Update Service. You do not really interact with the service directly, and it does what it is configured to do.  

Within WinHTTP, there is exactly one proxy configuration that is shared by all applications that leverage the WinHTTP API set for their web requests.  

The simplest way to view this configuration is via  netsh :  


C:\> netsh winhttp show proxy

Current WinHTTP proxy settings:
	Direct access (no proxy server)

In this case, we can see that I do not have anything configured for WinHTTP. Let's see what we can configure for this WinHTTP proxy. If I use  netsh winhttp set proxy  I can adjust the WinHTTP proxy configuration. (Note, this needs to be done as an Administrator).  


C:\> netsh winhttp set proxy
Current WinHTTP proxy settings:
	Proxy Server(s)	:
	Bypass List		:


With the configuration in place, my WinHTTP web requests will be sent to the proxy server  on TCP port  88  for  ALL  traffic except for  

Pretty cool right? And If I want to remove this configuration, I can clear it out with  netsh winhttp reset proxy .  

C:\> netsh winhttp reset proxy

Current WinHTTP proxy settings:

	Direct access (no proxy server).

Unfortunately, there is not an effective way to configure something like this environment wide other than deploying the WinHTTP registry configuration via Group Policy.  


Registry Key: HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections  
REG_BINARY: WinHttpSettings 

C:\> reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections"  

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections
    WinHttpSettings    REG_BINARY    2800000000000000010000000000000000000000  




I cannot stress this enough.   


Do not manually edit this registry key .   


This is a binary key that is referenced by many different services in the OS (operating systems). It is too easy to misconfigure for it to be a recommended method of adjusting the settings.  




WinINET is a super-set of WinHTTP that has a subset of features that may be more appealing to application developers. (For more details please see  WinINET vs WinHTTP ).  


The WinINET proxy (sometimes called the Internet Explorer proxy) is a per user proxy configuration that supports features such as:  


  • WPAD  
  • Auto Configuration URLs (proxy.pac)  
  • Static proxy and bypass list  

The configuration for this proxy can be found under the setting page  Network & internet > Proxy  or to get there quickly  ms-settings:network-proxy .  


Additionally, unlike WinHTTP there are Group Policies available to configure the proxy under Group Policy Preferences -> Control Panel Settings -> Internet Settings  




With the ability to configure a proxy-per user you may think "Wow that is awesome! Why can't WinHTTP do that?", well I have great news! Since Windows 8.1, WinHTTP will by default leverage the AutoConfig URL for the current user!  




Now with this degree of configurability things can get a bit messy. There are some common gotchas when it comes to proxies on Windows.  


WinINET proxy is a per user proxy configuration.  


Here is a common scenario.   


An enterprise environment will configure all network traffic to go through a proxy. If traffic does  NOT  go through that proxy, it will be dropped by their firewall. They have configured their users to leverage a static WinINET proxy.  


This is a great idea if you are concerned about reaching out to open internet endpoints without any kind of auditing. However, there is a problem. There are plenty of services within Windows that do NOT run as the logged in user and thus will not have their proxy configuration made available to them.  


In this case, here are a few options:  


  • Okay: Configure the WinHTTP proxy with the same configuration as the WinINET settings for the user  
  • Bad: Set the WinINET settings for the user context that the relevant applications  


I have ranked the options in order from most supportable to least supportable. The reason I have ranked them this way is that as you move down the options it becomes more difficult to detect that these changes are in place. If your team is not diligent with their change control, it can be easy to forget that you made the chance in the first place, leading to time lost on troubleshooting because the proxy isn’t working as you expect.  


The best option is to configure the group policy “Make proxy settings per-machine (rather than per-user)". Since this option is deployed via group policy, it is easy to adjust throughout the enterprise. The okay option is a single configuration for the machine specifically. The bad option is to go through every unconfigured user context and set them. This makes any changes down the line much more difficult and is an involved process.  


VPNs (virtual private networks)  


Here is a common scenario.   


There is a proxy server located on the enterprise network. Users are working from home or at a different location. Users can access enterprise resources via a VPN. The security team has determined that all network traffic  MUST  go through the proxy.  


The problem here is that until users connect to the VPN, they  CANNOT  access the enterprise proxy server. If a static proxy server (WinINET or WinHTTP) is configured but is not reachable then the network traffic will not be allowed out of the machine.  

What can we do about this? Luckily, very smart Windows developers many years ago thought about this scenario and added the option to configure a proxy server based on a VPN connection.  


This option can be defined in the VPN manually via the settings.  








Or included in the  VPN profile definition .  


It is important to note that this option is  ONLY  available for Force-Tunnel VPNs not Split-Tunnel VPNs.  


Proxies with .NET Applications  


Everything I have discussed so far has been in the context of your native Windows C/C++ application. And while this holds true for .NET applications as well there is an additional caveat.  

Within the .NET framework you can configure a default proxy for the framework itself.  This is done by configuring the <defaultProxy> element within the Machine.config .NET framework schema file. This configuration is available per .NET framework version, but generally it will be found in


 C:\Windows\Microsoft.NET\<.NET Version>\Config\


Replacing <.NET Version> with the version of .NET in question.    


Proxy server failures  


Like we have talked about previously, there are a few ways that we can configure Windows proxies.  

  • Automatically detect settings (WPAD)  
  • AutoConfig URL  
  • Static Proxy with bypass list  

But what is the priority here?  From my own testing (and thus subject to change) here is what I have been able to determine:  







  1. Do I have a valid WPAD configure?  
    • If yes, use it for the AutoConfig URL or static proxy defined in the WPAD.dat 
    • If not, to any of the above proceed.  
  2. Do I have a valid AutoConfig URL?
    • If yes, can I contact the specified server? 
    • If yes, can I process the proxy.pac file?
    • If the answer to any of the above is no, proceed.  
  3. Do I have a valid static proxy?
    • If yes, can I contact the proxy server?  
      • If not, drop the traffic.  
      • If yes, use the proxy server.  


This can lead to oddities when the expectation is to use the proxy.pac file. My recommendation is to think of the static proxy as a catch all. If I cannot leverage a proxy.pac or WPAD, do I want to send the traffic through a proxy? If the answer is yes, also define the static proxy. If not, just use the AutoConfig URL or WPAD.  


I don't want to use WPAD  


There are a few reasons why you might not want to use WPAD and since the proxy configuration is per user context this can be tricky.  


As I called out earlier there is an option to configure proxies on a per-machine basis, but that may be overkill for what you are trying to do.  


An alternative may be to just disable WPAD itself. Since Windows 10 1809 and Windows Server 2019, you can disable WPAD through the following registry key:  


Registry Key: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp  
REG_DWORD: DisableWpad  


Set the value to 1 to disable WPAD, remove or set it to 0 to leave WPAD in its default state.  


Please refer to  How to disable WPAD  for most up to date instructions.  




This is all well and good for how things  should  operate but there are a few exceptions here. The information outlined above is in the case of Windows in-box components or applications that are leveraging the default configuration for these API sets.  

Applications can define their own proxy to overwrite the default WinHTTP and WinINET behavior. Applications can also avoid leveraging these API sets all together where Windows will have no insight into how they have made their configurations.  

If you do not know if an application you rely upon leverages the Windows proxy, please consult your application vendor for additional details.  


Closing out  


The Windows proxies are flexible, and through careful testing and investigation, I am confident that you and your team will find the correct configuration to meet your needs. Catch y’all later!  


Leave a Reply

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.