Basic Auth: Encode special characters in password #723
Description
Dear Maintainers,
first of all, thanks a lot for your work. This library is awesome!
I'm not quite sure if my finding is really a bug or intended. Feel free to close this issue if it's intended.
For my current project I like to ask the user for the git repository url and credentials.
Before I actually clone the git repo, I would like to show the user if the given url and credentials are valid and if I'm able to clone the repository in the next step.
This was actually quite straight forward with small information from other (closed) issues.
The main issue I had was the authentication via basic auth. I use a very "secure" password which also includes special characters like "@" and "?" and so on. Every time I used my "secure" password with special characters, I got an access denied error. Please see this code as an example:
// Create new endpoint
ep, err := transport.NewEndpoint(repo.URL)
if err != nil {
os.Exit(1)
}
if repo.Username != "" && repo.Password != "" {
ep.User = repo.Username
ep.Password = repo.Password
}
// Create client
cl, err := client.NewClient(ep)
if err != nil {
os.Exit(1)
}
// Open new session
s, err := cl.NewUploadPackSession(ep, nil)
if err != nil {
os.Exit(1)
}
defer s.Close()
// Get advertised references (e.g. branches)
// ep.User = ""
// ep.Password = ""
ar, err := s.AdvertisedReferences()
...
If you run this code with a password that has special characters, you will get a nice access denied.
But if you clear the password and username before the command s.AdvertisedReferences()
is executed, it will work. (see the last two lines which are commented)
Why is that happening?
The problem is that the basic auth credentials will be added multiple times and for one routine the password is not URL encoded which is required.
The first time it will be added:
go-git/plumbing/transport/http/common.go
Line 116 in f6aca08
And the second time:
go-git/plumbing/transport/http/common.go
Line 34 in f6aca08
The second time is actually the bad part. This will generate the complete URL without actually encoding the password and is adding the basic auth credentials the second time without being required.