mirror of
https://github.com/golang/net.git
synced 2026-03-31 10:27:08 +09:00
Revert "http2: add X-Content-Type-Options automatically to prevent sniffing"
This reverts commit f73e4c9ed3.
Reason for revert: This turned out to cause more churn and provide less
security than expected.
Updates golang/go#24513
Change-Id: I2c8d0c39f8759ec8895a3261c91a98aeb2303ede
Reviewed-on: https://go-review.googlesource.com/117955
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
@@ -14,21 +14,6 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SniffedContentType reports whether ct is a Content-Type that is known
|
||||
// to cause client-side content sniffing.
|
||||
//
|
||||
// This provides just a partial implementation of mime.ParseMediaType
|
||||
// with the assumption that the Content-Type is not attacker controlled.
|
||||
func SniffedContentType(ct string) bool {
|
||||
if i := strings.Index(ct, ";"); i != -1 {
|
||||
ct = ct[:i]
|
||||
}
|
||||
ct = strings.ToLower(strings.TrimSpace(ct))
|
||||
return ct == "text/plain" || ct == "application/octet-stream" ||
|
||||
ct == "application/unknown" || ct == "unknown/unknown" || ct == "*/*" ||
|
||||
!strings.Contains(ct, "/")
|
||||
}
|
||||
|
||||
// ValidTrailerHeader reports whether name is a valid header field name to appear
|
||||
// in trailers.
|
||||
// See RFC 7230, Section 4.1.2
|
||||
|
||||
@@ -2312,7 +2312,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
||||
isHeadResp := rws.req.Method == "HEAD"
|
||||
if !rws.sentHeader {
|
||||
rws.sentHeader = true
|
||||
|
||||
var ctype, clen string
|
||||
if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
|
||||
rws.snapHeader.Del("Content-Length")
|
||||
@@ -2326,7 +2325,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
||||
if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
|
||||
clen = strconv.Itoa(len(p))
|
||||
}
|
||||
|
||||
_, hasContentType := rws.snapHeader["Content-Type"]
|
||||
if !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 {
|
||||
if cto := rws.snapHeader.Get("X-Content-Type-Options"); strings.EqualFold("nosniff", cto) {
|
||||
@@ -2339,20 +2337,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
||||
ctype = http.DetectContentType(p)
|
||||
}
|
||||
}
|
||||
|
||||
var noSniff bool
|
||||
if bodyAllowedForStatus(rws.status) && (rws.sentContentLen > 0 || len(p) > 0) {
|
||||
// If the content type triggers client-side sniffing on old browsers,
|
||||
// attach a X-Content-Type-Options header if not present (or explicitly nil).
|
||||
if _, ok := rws.snapHeader["X-Content-Type-Options"]; !ok {
|
||||
if hasContentType {
|
||||
noSniff = httpguts.SniffedContentType(rws.snapHeader.Get("Content-Type"))
|
||||
} else if ctype != "" {
|
||||
noSniff = httpguts.SniffedContentType(ctype)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var date string
|
||||
if _, ok := rws.snapHeader["Date"]; !ok {
|
||||
// TODO(bradfitz): be faster here, like net/http? measure.
|
||||
@@ -2371,7 +2355,6 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
|
||||
endStream: endStream,
|
||||
contentType: ctype,
|
||||
contentLength: clen,
|
||||
noSniff: noSniff,
|
||||
date: date,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -1810,7 +1810,6 @@ func TestServer_Response_TransferEncoding_chunked(t *testing.T) {
|
||||
{":status", "200"},
|
||||
{"content-type", "text/plain; charset=utf-8"},
|
||||
{"content-length", strconv.Itoa(len(msg))},
|
||||
{"x-content-type-options", "nosniff"},
|
||||
}
|
||||
if !reflect.DeepEqual(goth, wanth) {
|
||||
t.Errorf("Got headers %v; want %v", goth, wanth)
|
||||
@@ -1999,7 +1998,6 @@ func TestServer_Response_LargeWrite(t *testing.T) {
|
||||
wanth := [][2]string{
|
||||
{":status", "200"},
|
||||
{"content-type", "text/plain; charset=utf-8"}, // sniffed
|
||||
{"x-content-type-options", "nosniff"},
|
||||
// and no content-length
|
||||
}
|
||||
if !reflect.DeepEqual(goth, wanth) {
|
||||
@@ -2214,7 +2212,6 @@ func TestServer_Response_Automatic100Continue(t *testing.T) {
|
||||
{":status", "200"},
|
||||
{"content-type", "text/plain; charset=utf-8"},
|
||||
{"content-length", strconv.Itoa(len(reply))},
|
||||
{"x-content-type-options", "nosniff"},
|
||||
}
|
||||
if !reflect.DeepEqual(goth, wanth) {
|
||||
t.Errorf("Got headers %v; want %v", goth, wanth)
|
||||
@@ -2938,7 +2935,6 @@ func testServerWritesTrailers(t *testing.T, withFlush bool) {
|
||||
{"trailer", "Transfer-Encoding, Content-Length, Trailer"},
|
||||
{"content-type", "text/plain; charset=utf-8"},
|
||||
{"content-length", "5"},
|
||||
{"x-content-type-options", "nosniff"},
|
||||
}
|
||||
if !reflect.DeepEqual(goth, wanth) {
|
||||
t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth)
|
||||
@@ -3330,7 +3326,6 @@ func TestServerNoDuplicateContentType(t *testing.T) {
|
||||
{":status", "200"},
|
||||
{"content-type", ""},
|
||||
{"content-length", "41"},
|
||||
{"x-content-type-options", "nosniff"},
|
||||
}
|
||||
if !reflect.DeepEqual(headers, want) {
|
||||
t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
|
||||
|
||||
@@ -145,10 +145,9 @@ func TestTransport(t *testing.T) {
|
||||
t.Errorf("Status = %q; want %q", g, w)
|
||||
}
|
||||
wantHeader := http.Header{
|
||||
"Content-Length": []string{"3"},
|
||||
"X-Content-Type-Options": []string{"nosniff"},
|
||||
"Content-Type": []string{"text/plain; charset=utf-8"},
|
||||
"Date": []string{"XXX"}, // see cleanDate
|
||||
"Content-Length": []string{"3"},
|
||||
"Content-Type": []string{"text/plain; charset=utf-8"},
|
||||
"Date": []string{"XXX"}, // see cleanDate
|
||||
}
|
||||
cleanDate(res)
|
||||
if !reflect.DeepEqual(res.Header, wantHeader) {
|
||||
|
||||
@@ -186,7 +186,6 @@ type writeResHeaders struct {
|
||||
date string
|
||||
contentType string
|
||||
contentLength string
|
||||
noSniff bool
|
||||
}
|
||||
|
||||
func encKV(enc *hpack.Encoder, k, v string) {
|
||||
@@ -223,9 +222,6 @@ func (w *writeResHeaders) writeFrame(ctx writeContext) error {
|
||||
if w.contentLength != "" {
|
||||
encKV(enc, "content-length", w.contentLength)
|
||||
}
|
||||
if w.noSniff {
|
||||
encKV(enc, "x-content-type-options", "nosniff")
|
||||
}
|
||||
if w.date != "" {
|
||||
encKV(enc, "date", w.date)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user