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
Closed

net/http: ListenAndServe is vulnerable to DNS rebinding attacks #23993

empijei opened this issue Feb 21, 2018 · 5 comments

Comments

@empijei
Copy link
Contributor

empijei 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
Copy link
Member

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!

@chrj
Copy link

chrj 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
Copy link
Contributor Author

empijei 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
Copy link
Contributor

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

@bradfitz bradfitz self-assigned this May 29, 2018
@gopherbot
Copy link

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

@golang golang locked and limited conversation to collaborators Jun 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants