Go Public Service Announcement

Proxy support for some Go applications is being unintentionally dropped with a simple change. If you’ve ever had to initiate a HTTP request from behind a forward proxy, you might recall doing something like:

$ https_proxy=https://proxy.corp.example.com:3128 \
    curl https://google.com/

Take the following example Go code which overrides an HTTP client’s DefaultTransport with a custom Transport in order to optionally verifies the server’s certificate chain and hostname:

return &http.Client{
  Transport: &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: skipValidateTLS},

The full implications of the code change aren’t obvious so let’s look at the code that defines DefaultTransport specifically Proxy:

var DefaultTransport RoundTripper = &Transport{
  Proxy: ProxyFromEnvironment,

And Transport given no Proxy value:

  // If Proxy is nil or returns a nil *URL, no proxy is used.
  Proxy func(*Request) (*url.URL, error)

By using a custom Transport without restoring the Proxy value - we’ve lost the functionality of ProxyFromEnvironment. I’ve observed this defect in popular vendor’s code, e.g. Splunk and Dynatrace and suspect it’s more widespread. Stay vigilant.