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

CNA snapshot 3b43bd86  ·  Known Issues › Current bugs  ·  source links pinned to 3b43bd86

✓

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 3b43bd86; 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, but a request without Content-Length (chunked included) still gets 200 and is dropped, and the declared length is never bounded. A short body is now refused with 400.

Identifier
CNA-BUG-156
Category
Bug
Subsystem
Networking & gamer services
Status
Narrowed (partially fixed; describes only what survives)
Verified against
CNA 3b43bd86 (3b43bd8687ed46523d873f9bec4b32bd8481dcb5)
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. A request without Content-Length, including a chunked one, is therefore answered 200 OK and dropped (an empty body is never queued). 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 3b43bd86. Not executed. The phone module's Development page already records the same response table as a maintainer note.

Narrowed at c6dec91f: 20fe6efd2 (MUSEUM-PHONE-001, 2026-10-22) made the body loop return false when recv reports end of stream or an error before the declared length arrived, so a peer that stops short now gets 400 and nothing is queued; the CnaNotificationLifecycle_truncated case of notification_lifecycle_test.cpp covers it. The length-less and unbounded-length halves are unchanged.

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; notification_lifecycle_test.cpp adds truncated and partial requests, which reach the 400 path. No test sends a chunked, length-less or oversized request.

Regression test

Three raw-socket cases against an open channel: a chunked body, a body without Content-Length, and a declared length above a fixed cap. Each must receive a 4xx status (411, 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