Skip to content

RFC 9110: reject header field names that are not a token - #732

Closed
arturobernalg wants to merge 1 commit into
apache:masterfrom
arturobernalg:header-name-token
Closed

arturobernalg wants to merge 1 commit into
apache:masterfrom
arturobernalg:header-name-token

Conversation

@arturobernalg

Copy link
Copy Markdown
Member

The name of a received header was taken as is, up to the colon. Against real classic and async servers, master answered 200 OK and exposed the names Foo Bar, X\x01Y, Foo\x7f, Foo\x09Bar and Foo;x. A recipient that parses names differently, such as a proxy in front of or behind HttpCore, can be made to disagree with it about which header was sent.

BufferedHeader and BasicLineParser now reject a name that is not a token (RFC 9110 section 5.6.2) with the ParseException they already throw for a malformed header, which both message parsers turn into a 400 or a failed message. The check is one pass over the name. With the change the same requests get 400 Bad Request and X-Good_1.a still gets 200.

Whitespace before the colon and obs-fold are handled as before.

Compatibility: a peer that sends names with characters such as @, [ or spaces now gets a 400 from a server, and a client now fails a response carrying such a name, where it used to be accepted. Dropping the offending header instead of failing the message on the lax parser would be the alternative.

The name of a received header was taken as is, up to the colon, so names
with spaces, control characters or delimiters were accepted and exposed
to the application. A recipient that parses names differently, such as
a proxy in front of or behind HttpCore, can be made to disagree with it
about which header was sent.

BufferedHeader and BasicLineParser now reject a name that is not a token
with the ParseException they already throw for a malformed header, which
the message parsers turn into a 400 or a failed message. The check is a
single pass over the name.
@arturobernalg
arturobernalg requested a review from ok2c November 1, 2026 13:34
@ok2c

ok2c commented Nov 1, 2026

Copy link
Copy Markdown
Member

@arturobernalg I am not in favor of this change. There can always be recipients that parse things differently. This does not justify adding a full god damn scan to each and every header token.

@ok2c

ok2c commented Nov 1, 2026

Copy link
Copy Markdown
Member

@arturobernalg A proper solution to the problem would be passing a char validation lambda or BitSet while reading the content from the session buffer. This can be considered but I do not see this a priority.

@arturobernalg

Copy link
Copy Markdown
Member Author

Thanks, Oleg. Agreed, the check should not cost a pass over every header name. I am closing this one.

A proper solution to the problem would be passing a char validation lambda or BitSet while reading the content from the session buffer. This can be considered but I do not see this a priority.

I will keep that in mind and I am not pursuing it now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants