CNA-BUG-156: HttpNotificationChannel answers length-less, chunked and truncated pushes with 200 and reads request bodies of unbounded size

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

ReadRequestBody's comment says unreadable pushes are refused rather than delivered truncated, but a request without Content-Length gets 200 and is dropped, a short body gets 200 and is queued truncated, and the length is never bounded.

Identifier
CNA-BUG-156
Category
Bug
Subsystem
Networking & gamer services
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
Microsoft::Phone::Notification::HttpNotificationChannel listener: the HTTP status a push sender receives and the bytes raised as HttpNotificationReceived

Expected behaviour

The comment above ReadRequestBody states the design: the channel “understands a request with a Content-Length and nothing else”, and chunked encoding and other forms “are not accepted rather than half-supported -- a push that this cannot read is better refused visibly than delivered truncated”. A sender should get an error status for a request the channel cannot read, and a raised notification should carry the whole body.

Actual behaviour at TARGET

ReadRequestBody reads until the blank line that ends the header block (a failed or closed connection, or a header block over 1 MiB, returns false and the worker answers 400). It then looks for content-length: anywhere in the lower-cased header block and parses it with strtoul; without it the length is 0. The body loop reads until that many bytes arrived or recv returns 0 or an error, and the function returns true either way. A request without Content-Length, including a chunked one, is therefore answered 200 OK and dropped (an empty body is never queued), and a peer that stops after fewer bytes than it declared gets 200 OK and its truncated body is queued and later raised. The declared length is never capped, so the worker's buffer grows with whatever a peer declares and sends.

Source locations

Evidence

Checked by reading HttpNotificationChannel.cpp at 009d40f5; the file is unchanged since the earlier recorded pin. Not executed. The phone module's Development page already records the same response table as a maintainer note.

Focused reproduction

No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.

Current tests

HttpNotificationChannelTests.cpp (WhatAServicePostsArrivesAsANotification and the PushNotificationSenderTest cases) sends only complete requests with a Content-Length. No test sends a chunked, length-less, truncated or oversized request or reaches the 400 path.

Regression test

Four raw-socket cases against an open channel: a chunked body, a body without Content-Length, a body shorter than declared followed by a normal close, and a declared length above a fixed cap. Each must receive a 4xx status (411, 400, 400, 413) and queue nothing.

Blast radius

Pushes from senders other than CNA's own push sender, which always sends a Content-Length and the whole body; senders that fail mid-body; memory use of the listener thread. CNA-to-CNA pushes that complete are unaffected.

Workaround

Send pushes with a Content-Length and the complete body; a port can validate each payload (an expected length or checksum) in its handler.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Maintainer workflow
Thread and callback map
Known issues
Bug index