Only normalize pre-colon whitespace for HTTP headers (#2172)

Keep headerScanner strict so malformed MIME header lines are still rejected.

Move trimming before ':' into the HTTP header handling paths that
intentionally normalize header names, and add a fuzz seed for the
regression case.
This commit is contained in:
Erik Dubbelboer
2026-04-04 11:24:04 +09:00
committed by GitHub
parent ab8c2aceea
commit a95a1ad11c
3 changed files with 14 additions and 1 deletions
+1
View File
@@ -153,6 +153,7 @@ func FuzzURIParse(f *testing.F) {
func FuzzTestHeaderScanner(f *testing.F) {
f.Add([]byte("Host: example.com\r\nUser-Agent: Go-http-client/1.1\r\nAccept-Encoding: gzip, deflate\r\n\r\n"))
f.Add([]byte("Content-Type: application/x-www-form-urlencoded\r\nContent-Length: 27\r\n\r\nname=John+Doe&age=30"))
f.Add([]byte(" 3 :\r\n\r\n"))
f.Fuzz(func(t *testing.T, data []byte) {
if !bytes.Contains(data, []byte("\r\n\r\n")) {
+13
View File
@@ -1300,6 +1300,7 @@ func (h *RequestHeader) AllInOrder() iter.Seq2[[]byte, []byte] {
var s headerScanner
s.b = h.rawHeaders
for s.next() {
s.key = trimTrailingSpace(s.key)
normalizeHeaderKey(s.key, h.disableNormalizing || bytes.IndexByte(s.key, ' ') != -1)
if len(s.key) > 0 {
if !yield(s.key, s.value) {
@@ -2693,6 +2694,10 @@ func parseTrailer(src []byte, dest []argsKV, disableNormalizing bool) ([]argsKV,
s.b = src
for s.next() {
// Trim trailing whitespace before the colon to normalize headers
// like "Content-Length :" to "Content-Length:".
s.key = trimTrailingSpace(s.key)
if len(s.key) == 0 {
continue
}
@@ -2978,6 +2983,10 @@ func (h *ResponseHeader) parseHeaders(buf []byte) (int, error) {
var kv *argsKV
for s.next() {
// Trim trailing whitespace before the colon to normalize headers
// like "Content-Length :" to "Content-Length:".
s.key = trimTrailingSpace(s.key)
if len(s.key) == 0 {
h.connectionClose = true
return 0, fmt.Errorf("invalid header key %q", s.key)
@@ -3104,6 +3113,10 @@ func (h *RequestHeader) parseHeaders(buf []byte) (int, error) {
s.b = buf
for s.next() {
// Trim trailing whitespace before the colon to normalize headers
// like "Content-Length :" to "Content-Length:".
s.key = trimTrailingSpace(s.key)
if len(s.key) == 0 {
h.connectionClose = true
return 0, fmt.Errorf("invalid header key %q", s.key)
-1
View File
@@ -53,7 +53,6 @@ func (s *headerScanner) next() bool {
s.err = fmt.Errorf("malformed MIME header line: %q", kv)
return false
}
k = trimTrailingSpace(k)
if !isValidHeaderKey(k) {
s.err = fmt.Errorf("malformed MIME header line: %q", kv)
return false