Commit d3c3aaa6 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http: revert CL 89275 (don't sniff Content-Type when nosniff set)

Also updates the bundled http2 to x/net/http2 git rev 49c15d80 for:

   http2: revert CL 107295 (don't sniff Content-type in Server when nosniff)
   https://golang.org/cl/126895

Fixes #24795

Change-Id: I6ae1a21c919947089274e816eb628d20490f83ce
Reviewed-on: https://go-review.googlesource.com/126896Reviewed-by: default avatarDamien Neil <dneil@google.com>
parent 9e2a4f4d
...@@ -677,10 +677,7 @@ for k := range m { ...@@ -677,10 +677,7 @@ for k := range m {
methods will return errors after a shutdown or close. methods will return errors after a shutdown or close.
</p> </p>
<p><!-- CL 89275 --> <!-- CL 89275 was reverted before Go 1.11 -->
The HTTP server will no longer automatically set the Content-Type if a
<code>Handler</code> sets the "<code>X-Content-Type-Options</code>" header to "<code>nosniff</code>".
</p>
<p><!-- CL 93296 --> <p><!-- CL 93296 -->
The constant <code>StatusMisdirectedRequest</code> is now defined for HTTP status code 421. The constant <code>StatusMisdirectedRequest</code> is now defined for HTTP status code 421.
......
...@@ -6135,16 +6135,8 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { ...@@ -6135,16 +6135,8 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
} }
_, hasContentType := rws.snapHeader["Content-Type"] _, hasContentType := rws.snapHeader["Content-Type"]
if !hasContentType && http2bodyAllowedForStatus(rws.status) && len(p) > 0 { if !hasContentType && http2bodyAllowedForStatus(rws.status) && len(p) > 0 {
if cto := rws.snapHeader.Get("X-Content-Type-Options"); strings.EqualFold("nosniff", cto) {
// nosniff is an explicit directive not to guess a content-type.
// Content-sniffing is no less susceptible to polyglot attacks via
// hosted content when done on the server.
ctype = "application/octet-stream"
rws.conn.logf("http2: WriteHeader called with X-Content-Type-Options:nosniff but no Content-Type")
} else {
ctype = DetectContentType(p) ctype = DetectContentType(p)
} }
}
var date string var date string
if _, ok := rws.snapHeader["Date"]; !ok { if _, ok := rws.snapHeader["Date"]; !ok {
// TODO(bradfitz): be faster here, like net/http? measure. // TODO(bradfitz): be faster here, like net/http? measure.
......
...@@ -3585,26 +3585,6 @@ func TestHeaderToWire(t *testing.T) { ...@@ -3585,26 +3585,6 @@ func TestHeaderToWire(t *testing.T) {
return nil return nil
}, },
}, },
{
name: "Nosniff without Content-type",
handler: func(rw ResponseWriter, r *Request) {
rw.Header().Set("X-Content-Type-Options", "nosniff")
rw.WriteHeader(200)
rw.Write([]byte("<!doctype html>\n<html><head></head><body>some html</body></html>"))
},
check: func(got, logs string) error {
if !strings.Contains(got, "Content-Type: application/octet-stream\r\n") {
return errors.New("Output should have an innocuous content-type")
}
if strings.Contains(got, "text/html") {
return errors.New("Output should not have a guess")
}
if !strings.Contains(logs, "X-Content-Type-Options:nosniff but no Content-Type") {
return errors.New("Expected log message")
}
return nil
},
},
} }
for _, tc := range tests { for _, tc := range tests {
ht := newHandlerTest(HandlerFunc(tc.handler)) ht := newHandlerTest(HandlerFunc(tc.handler))
......
...@@ -1360,16 +1360,8 @@ func (cw *chunkWriter) writeHeader(p []byte) { ...@@ -1360,16 +1360,8 @@ func (cw *chunkWriter) writeHeader(p []byte) {
// If no content type, apply sniffing algorithm to body. // If no content type, apply sniffing algorithm to body.
_, haveType := header["Content-Type"] _, haveType := header["Content-Type"]
if !haveType && !hasTE && len(p) > 0 { if !haveType && !hasTE && len(p) > 0 {
if cto := header.get("X-Content-Type-Options"); strings.EqualFold("nosniff", cto) {
// nosniff is an explicit directive not to guess a content-type.
// Content-sniffing is no less susceptible to polyglot attacks via
// hosted content when done on the server.
setHeader.contentType = "application/octet-stream"
w.conn.server.logf("http: WriteHeader called with X-Content-Type-Options:nosniff but no Content-Type")
} else {
setHeader.contentType = DetectContentType(p) setHeader.contentType = DetectContentType(p)
} }
}
} else { } else {
for _, k := range suppressedHeaders(code) { for _, k := range suppressedHeaders(code) {
delHeader(k) delHeader(k)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment