]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: drop headers with invalid keys in Header.Write
authorDamien Neil <dneil@google.com>
Mon, 16 Aug 2021 17:46:06 +0000 (10:46 -0700)
committerDamien Neil <dneil@google.com>
Mon, 16 Aug 2021 20:02:13 +0000 (20:02 +0000)
Don't let handlers inject unexpected headers by setting keys like:
w.Header().Set("Evil: x\r\nSmuggle", y)

Fixes #47711.

Change-Id: I459ce1c79bc273a84230a0f5b665f81c46dbc672
Reviewed-on: https://go-review.googlesource.com/c/go/+/342530
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>

src/net/http/header.go
src/net/http/header_test.go

index 4c72dcb2c88d254f3e8b81a483bb6b40079f4b37..cc9c28e3d0d6203a17242f0a048adbb9de04caf7 100644 (file)
@@ -13,6 +13,8 @@ import (
        "strings"
        "sync"
        "time"
+
+       "golang.org/x/net/http/httpguts"
 )
 
 // A Header represents the key-value pairs in an HTTP header.
@@ -192,6 +194,13 @@ func (h Header) writeSubset(w io.Writer, exclude map[string]bool, trace *httptra
        kvs, sorter := h.sortedKeyValues(exclude)
        var formattedVals []string
        for _, kv := range kvs {
+               if !httpguts.ValidHeaderFieldName(kv.key) {
+                       // This could be an error. In the common case of
+                       // writing reponse headers, however, we have no good
+                       // way to provide the error back to the server
+                       // handler, so just drop invalid headers instead.
+                       continue
+               }
                for _, v := range kv.values {
                        v = headerNewlineToSpace.Replace(v)
                        v = textproto.TrimString(v)
index 47893629194b6a6dedde343b06c73ac0db976f34..57d16f51a5d62e662847b47fbf33203048c8b8bb 100644 (file)
@@ -89,6 +89,19 @@ var headerWriteTests = []struct {
                        "k4: 4a\r\nk4: 4b\r\nk6: 6a\r\nk6: 6b\r\n" +
                        "k7: 7a\r\nk7: 7b\r\nk8: 8a\r\nk8: 8b\r\nk9: 9a\r\nk9: 9b\r\n",
        },
+       // Tests invalid characters in headers.
+       {
+               Header{
+                       "Content-Type":             {"text/html; charset=UTF-8"},
+                       "NewlineInValue":           {"1\r\nBar: 2"},
+                       "NewlineInKey\r\n":         {"1"},
+                       "Colon:InKey":              {"1"},
+                       "Evil: 1\r\nSmuggledValue": {"1"},
+               },
+               nil,
+               "Content-Type: text/html; charset=UTF-8\r\n" +
+                       "NewlineInValue: 1  Bar: 2\r\n",
+       },
 }
 
 func TestHeaderWrite(t *testing.T) {