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: ListenAndServe is vulnerable to DNS rebinding attacks #23993

Closed
empijei opened this issue Feb 21, 2018 · 5 comments

Comments

Projects
None yet
5 participants
@empijei
Copy link
Contributor

commented Feb 21, 2018

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

go version go1.10 linux/amd64

Does this issue reproduce with the latest release?

Yes

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

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/rob/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/rob/go/gopath"
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build916972665=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I wrote this small sample http listener code:

package main

import "net/http"

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello World"))
	})
	http.ListenAndServe("localhost:8080", nil)
}

This, as expected, only listens for loopback connections, and it does not respond to requests coming from outside the machine.

I then tried, from the local host, to perform a request with an arbitrary Host header:

 curl localhost:8080 --verbose --header "Host: victim.com"
* Rebuilt URL to: localhost:8080/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: victim.com
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Wed, 21 Feb 2018 10:17:55 GMT
< Content-Length: 11
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
Hello World%       

What did you expect to see?

Either the request to fail or the documentation for ListenAndServe or Handler to say that the local listener does not check for the Host header and is thus vulnerable to DNS rebinding attacks.

What did you see instead?

The request obtaining a response, without checks on the host header, and without any documentation on this issue.

@mikioh mikioh changed the title http.ListenAndServe is vulnerable to DNS rebinding attacks net/http: ListenAndServe is vulnerable to DNS rebinding attacks Feb 21, 2018

@odeke-em

This comment has been minimized.

Copy link
Member

commented Feb 21, 2018

Thank you for reporting this @empijei!

I'll page some of the folks on the net/http and security crews @bradfitz @agl @tombergan @FiloSottile.

Depending on the confirmation and severity of the issue after we evaluate it, perhaps in the future, please report security issues first to security@golang.org as detailed at https://golang.org/security, but either way, thank you for reporting it!

@odeke-em odeke-em added the Security label Feb 21, 2018

@chrj

This comment has been minimized.

Copy link

commented Feb 21, 2018

Check the documentation for ServeMux

In order to only serve your handle for a specific host, your pattern should read:

http.HandleFunc("example.com/", func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello World"))
})

Then a request for victim.com will return a 404.

@empijei

This comment has been minimized.

Copy link
Contributor Author

commented Feb 21, 2018

Oh, I didn't know that, thanks.
Do you think it should be mentioned somewhere else? Or maybe this issue should be described in the documentation?

@bradfitz bradfitz added this to the Go1.11 milestone Feb 21, 2018

@bradfitz

This comment has been minimized.

Copy link
Member

commented Feb 21, 2018

I suppose we could add some docs about the Host header somewhere.

@bradfitz bradfitz self-assigned this May 29, 2018

@gopherbot

This comment has been minimized.

Copy link

commented May 29, 2018

Change https://golang.org/cl/115116 mentions this issue: net/http: document that Handlers are resposible for validating Host headers

@gopherbot gopherbot closed this in ad7320a Jun 15, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.