mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
net/http: make Server validate Host headers
Fixes #11206 (that we accept invalid bytes) Fixes #13624 (that we don't require a Host header in HTTP/1.1 per spec) Change-Id: I4138281d513998789163237e83bb893aeda43336 Reviewed-on: https://go-review.googlesource.com/17892 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
c2fb457ef7
commit
6e11f45ebd
3 changed files with 139 additions and 9 deletions
|
|
@ -686,7 +686,7 @@ func (c *conn) readRequest() (w *response, err error) {
|
|||
peek, _ := c.bufr.Peek(4) // ReadRequest will get err below
|
||||
c.bufr.Discard(numLeadingCRorLF(peek))
|
||||
}
|
||||
req, err := ReadRequest(c.bufr)
|
||||
req, err := readRequest(c.bufr, false)
|
||||
c.mu.Unlock()
|
||||
if err != nil {
|
||||
if c.r.hitReadLimit() {
|
||||
|
|
@ -697,6 +697,18 @@ func (c *conn) readRequest() (w *response, err error) {
|
|||
c.lastMethod = req.Method
|
||||
c.r.setInfiniteReadLimit()
|
||||
|
||||
hosts, haveHost := req.Header["Host"]
|
||||
if req.ProtoAtLeast(1, 1) && (!haveHost || len(hosts) == 0) {
|
||||
return nil, badRequestError("missing required Host header")
|
||||
}
|
||||
if len(hosts) > 1 {
|
||||
return nil, badRequestError("too many Host headers")
|
||||
}
|
||||
if len(hosts) == 1 && !validHostHeader(hosts[0]) {
|
||||
return nil, badRequestError("malformed Host header")
|
||||
}
|
||||
delete(req.Header, "Host")
|
||||
|
||||
req.RemoteAddr = c.remoteAddr
|
||||
req.TLS = c.tlsState
|
||||
if body, ok := req.Body.(*body); ok {
|
||||
|
|
@ -1334,6 +1346,13 @@ func (c *conn) setState(nc net.Conn, state ConnState) {
|
|||
}
|
||||
}
|
||||
|
||||
// badRequestError is a literal string (used by in the server in HTML,
|
||||
// unescaped) to tell the user why their request was bad. It should
|
||||
// be plain text without user info or other embeddded errors.
|
||||
type badRequestError string
|
||||
|
||||
func (e badRequestError) Error() string { return "Bad Request: " + string(e) }
|
||||
|
||||
// Serve a new connection.
|
||||
func (c *conn) serve() {
|
||||
c.remoteAddr = c.rwc.RemoteAddr().String()
|
||||
|
|
@ -1399,7 +1418,11 @@ func (c *conn) serve() {
|
|||
if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
|
||||
return // don't reply
|
||||
}
|
||||
io.WriteString(c.rwc, "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n400 Bad Request")
|
||||
var publicErr string
|
||||
if v, ok := err.(badRequestError); ok {
|
||||
publicErr = ": " + string(v)
|
||||
}
|
||||
io.WriteString(c.rwc, "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n400 Bad Request"+publicErr)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue