Skip to content

net/mail: characters allowed in RFC 5322 are invalid while parsing email header #58862

@iredmail

Description

@iredmail

What version of Go are you using (go version)?

$ go version
go version go1.20.1 darwin/amd64

Does this issue reproduce with the latest release?

Yes.

What did you do?

Create an empty directory and save code below in main.go, run go mod tidy && go run ..
Note: it contains header Custom/Header: v.

package main

import (
	"log"
	"net/mail"
	"strings"
)

func main() {
	msg := `Date: Mon, 23 Jun 2015 11:40:36 -0400
From: Gopher <[email protected]>
To: Another Gopher <[email protected]>
Subject: Gophers at Gophercon
Custom/Header: v

Message body
`

	r := strings.NewReader(msg)
	m, err := mail.ReadMessage(r)
	if err != nil {
		log.Fatal(err)
	}

	println(m.Header.Get("Custom/Header"))
}

What did you expect to see?

Print value of email header Custom/Header: v

What did you see instead?

2023/03/04 20:57:52 malformed MIME header line: Custom/Header: v
exit status 1

Function mail.ReadMessage() calls textproto.ReadMIMEHeader(), it calls internal function validHeaderValueByte() (in net/textproto) to validate characters in email header field, / in header field is considered as invalid.

The problem is, validHeaderValueByte() is designed to validate characters in HTTP header, not email header.

According to RFC 5322 "Internet Message Format", section "2.2 Header fields":

   A field name MUST be composed of printable US-ASCII characters (i.e.,
   characters that have values between 33 and 126, inclusive), except
   colon.

Here's full list of printable US-ASCII characters:
https://www.ascii-code.com/characters/printable-characters

For example, characters /, *, [, ] are allowed in email header field according to RFC doc, but it won't pass current validHeaderFieldByte() because it's disallowed in http header field. This causes parse error as shown in above sample code. I believe there're some similar issues caused by validHeaderValueByte() too.

We may need a new exported function like ReadMIMEHeader but for email (maybe name it as ReadEmailMIMEHeader()), and allow characters as defined in RFC 5322, but other code in net/textproto may need some changes too.

Metadata

Metadata

Assignees

Labels

FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions