Skip to content

net/url: omit URL's password when stringifying URL in Error #24572

@ejholmes

Description

@ejholmes

It's fairly common practice to pack basic auth credentials in a URL string:

http://user:pass@localhost:1234

When basic authentication credentials are provided in this manner, net/http will automatically set the Authorization header before sending the request, however, net/http leaves the original URL string un-modified.

This has the potential to create nasty little security problems when errors occur. Consider the following program:

package main

import (
	"log"
	"net/http"
)

func main() {
	_, err := http.Get("http://user:pass@localhost:12345")
	log.Fatal(err)
}

When ran, you'll see the following output:

2018/03/27 19:44:44 Get http://user:pass@localhost:12345: dial tcp [::1]:12345: getsockopt: connection refused
exit status 1

It's fairly common practice in Go programs to bubble errors up the call stack. In many cases, these errors can be shown to untrusted parties if care isn't taken. Obviously, there's a lot of things that can be done to mitigate this (don't pass creds in the URL string, don't bubble up internal errors to untrusted parties, use http signatures instead of long lived creds, etc), but I think Go could provide a better secure default here. Equivalent versions in ruby and python will not display the credentials.

I'd propose that this block be changed so that, if the condition matches, the basic auth creds are stripped from the raw URL string, so that they won't end up in url.Error's.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions