Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: Authorization header stripping in client on redirects incorrect when redirecting from http to https #35104

Closed
h3kker opened this issue Oct 23, 2019 · 9 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@h3kker
Copy link

h3kker commented Oct 23, 2019

What version of Go are you using (go version)?

$ go version
go version go1.12.4 darwin/amd64

Does this issue reproduce with the latest release?

Should (source code at https://golang.org/src/net/http/client.go indicates that)

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/heinz.ekker/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/heinz.ekker/coden/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.12.4/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.12.4/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/dh/6nzg_lhs19l_kxwv21s_8wz80000gn/T/go-build031339938=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

A go cli application (singularity, https://github.com/sylabs/singularity) tries to make a http request with a Authorization: Bearer .. header.

What did you expect to see?

The request on the server with a Authorization: Bearer ... header

What did you see instead?

Header was stripped from the request. Trying to do the same request with the same headers with curl leaves the header intact.

I think the problem in this case is that

As far as I can see there is a problem in isDomainOrSubdomain. It does an equality or suffix match on the original + redirected hostnames. But the hostnames come from canonicalAddr, which appends the port from the protocol. So it would check whether singularity.example.com:80 is a suffix of singularity.example.com:443, which it isn't, and then strip the header.

It seems a bit strange, in this case it would kick in a security check for something that actually improves security ;-) It is either a bug in the code or in the documentation, which does not mention protocol or ports.

@dmitshur dmitshur added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Oct 23, 2019
@dmitshur dmitshur changed the title Authorization header stripping in src/net/http/client on redirects incorrect when redirecting from http to https net/http: Authorization header stripping in client on redirects incorrect when redirecting from http to https Oct 23, 2019
@dmitshur
Copy link
Contributor

Thanks for the report.

/cc @bradfitz

@neild
Copy link
Contributor

neild commented Oct 17, 2020

From my reading, libcurl's behavior is to keep sensitive headers only when the hostname is an exact match (ignoring the port).

I think that if we're going to preserve a header on a redirect from example.com to foo.example.com, then there's no reason not to preserve it on a redirect from one port to another on the same host. (Perhaps we should refuse to copy headers on a security downgrade from https to http?)

@manigandand
Copy link

If the sensitive headers can be copied for subdomains then why not for the same host without a port.

I expect the headers to be copied to the same host of the different ports.

Redirecting from api.gopherhut.com:80 to api.gopherhut.com:443 I expect the sensitive headers also should be sent.
Currently, this is not happening because we are checking for exact host matches from the different canonical host addresses.

func isDomainOrSubdomain(sub, parent string) bool {
	if sub == parent {
		return true
	}
	// If sub is "foo.example.com" and parent is "example.com",
	// that means sub must end in "."+parent.
	// Do it without allocating.
	if !strings.HasSuffix(sub, parent) {
		return false
	}
	return sub[len(sub)-len(parent)-1] == '.'
}

@asutosh97
Copy link

Yes, agree with what @manigandand said
Maybe we should just simply check the hostnames and leave out the ports when doing the check

@hgoku
Copy link

hgoku commented Jun 29, 2022

Hello, the problem still occurs using go1.17.2 .
Want to know if there are any updates on this issue?

wubin1989 added a commit to wubin1989/go that referenced this issue Jul 12, 2022
@wubin1989
Copy link

Hello, the problem still occurs using go1.18. I submit a pr to fix it.

@gopherbot
Copy link

Change https://go.dev/cl/417014 mentions this issue: net/http: copy Authorization header when redirect from http to https Fixes #35104

comfortablynumb added a commit to comfortablynumb/go that referenced this issue Aug 19, 2022
… domain / subdomain even if ports are different (i.e.: redirect from http to https). Fixes issue golang#35104
@gopherbot
Copy link

Change https://go.dev/cl/424935 mentions this issue: net/http: keep sensitive headers on redirects to the same domain - Fixes #35104

@comfortablynumb
Copy link
Contributor

@wubin1989 : Your change is removing ports 80 and 443 from a map that is used in the canonicalAddr function, which must always return host:port. If those ports are not present on this map, it will return host:. This function is also used in other structs of the net/http package (like Transport) which I think require the port.

I've created another PR which basically keeps that function untouched and adds another one that returns only the host. I've also updated some of the original tests which were assuming that redirects to the same host + different port shouldn't propagate these headers: #54539

comfortablynumb added a commit to comfortablynumb/go that referenced this issue Aug 20, 2022
@seankhliao seankhliao added this to the Backlog milestone Aug 27, 2022
comfortablynumb added a commit to comfortablynumb/go that referenced this issue Dec 11, 2022
@dmitshur dmitshur added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jan 26, 2023
@dmitshur dmitshur modified the milestones: Backlog, Go1.21 Jan 26, 2023
@golang golang locked and limited conversation to collaborators Jan 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants