libwww-perl / libwww-perl/HTTP-Daemon

Content_Length is silently aliased to Content-Length on incoming requests

Open
#86 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Perl
Stars
6
Forks
17
PR merge metrics
No merged PRs in 30d

Description

Split out from #56 / CVE-2022-31081 (POC #5).

Content_Length and Content-Length are syntactically distinct header field names. Per RFC 9110 §5.1, field-name = token; per RFC 9110 §5.6.2, tchar includes both _ and -, so both names are valid tokens. Field names are case-insensitive per RFC 9110 §5.1, but case-insensitivity does not extend to _ vs - — these are simply different fields.

$HTTP::Headers::TRANSLATE_UNDERSCORE defaults to 1, so an incoming Content_Length: 3 is stored as Content-Length: 3. The fat-comma ergonomics this enables are useful for outgoing message construction, but on the server side it conflates two distinct fields.

The multi-value mismatch case (Content_Length: 3 + Content-Length: 22) is now caught by the CVE-2022-31081 fix at lib/HTTP/Daemon.pm:296-315, since the joined 3, 22 fails the "all values equal" check and returns 400.

Security relevance — still real

A request with Content_Length: N alone (no Content-Length) frames as zero-body for a strict proxy that treats underscored headers as non-standard (e.g. nginx's default underscores_in_headers off), but as N bytes for HTTP::Daemon — a CL.0 desync. Risk exists against any proxy that forwards underscored headers verbatim.

Proposed fix

@vanHoesel suggested in #56 adding an HTTP::Daemon constructor option underscores_in_headers / drop_underscores that filters underscored header names before they reach HTTP::Headers::push_header.

Default value (strip vs. translate) is the contentious bit — defaulting to strip is safer but breaks any user relying on the alias. A middle option: leave HTTP::Headers behavior unchanged but have HTTP::Daemon strip underscored header names from incoming requests by default, since the daemon is the server-side surface where the smuggling risk lives.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading lib/HTTP/Daemon.pm:296-315 and tracing incoming headers into HTTP::Headers::push_header, then review the context in #56 and CVE-2022-31081. The maintainer decision is whether HTTP::Daemon should strip underscored incoming headers by default or expose an option; done means the chosen behavior prevents the described framing mismatch without an unreviewed compatibility change.

Written by the indexing model from the issue text.

Assessment

Tech stack
perl
Domain
backend, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.