Skip to content

fix(routes): harden POST /me/inbox/send - #54

Merged
TheGreatAxios merged 1 commit into
cl-9435-mailbox-allocate-uids-atomically-and-enforce-uniquenessfrom
cl-9436-mailbox-harden-the-send-route-recipient-injection-display
Sep 27, 2026
Merged

TheGreatAxios merged 1 commit into
cl-9435-mailbox-allocate-uids-atomically-and-enforce-uniquenessfrom
cl-9436-mailbox-harden-the-send-route-recipient-injection-display

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Stacked on fix(store): allocate uids in Postgres and enforce uid and Message-ID uniqueness #53.
  • POST /me/inbox/send returns 400 when a recipient contains CR, LF or NUL. The check runs before the Sent append and deliver, so a header-injection payload never reaches the envelope cache or the host transport.
  • generateMailboxMessageId mints from the sender's addr-spec (@intx/mime extractAddrSpec), so the send route and writeMailboxMessage both get <uuid@domain> (persist keeps the inbound message's own Message-ID), and a senderAddressFor that returns "Name <addr>" no longer 500s. A sender with no parseable addr-spec (a bare name, or a trailing comment like p@t.example (c)) falls back to the hub.invalid domain.
  • The route enforces assertMailboxFrameBytes. A RangeError from building the frame or from the cap is a 400.

Verification

  • e2e/mount-send.test.ts: CR/LF/NUL recipients are 400 with no Sent row and no delivery; a display-name sender gets <uuid@t1.example>; a bare Pat sender gets <uuid@hub.invalid>; a body at the frame cap is 400 with no Sent row and no delivery. All but the hub.invalid case fail on fix(store): allocate uids in Postgres and enforce uid and Message-ID uniqueness #53.
  • src/frame.test.ts: <p@t.example> mints <uuid@t.example>; p@t.example (c) mints a well-formed id with no comment in it.
  • bun run check, build, test:e2e and the pack smoke pass locally.

Closes CL-9436

A recipient carrying CR, LF or NUL is a 400 before anything is appended
or handed to deliver, so a header-injection payload never reaches the
envelope cache or the host transport. The Message-ID is minted from the
addr-spec of the sender (@intx/mime extractAddrSpec), so a
senderAddressFor that returns "Name <addr>" no longer 500s, and a sender
with no addr-spec falls back to hub.invalid. A RangeError from building
the frame, including the frame-byte cap the route now enforces with
assertMailboxFrameBytes, is a 400.
@TheGreatAxios
TheGreatAxios force-pushed the cl-9436-mailbox-harden-the-send-route-recipient-injection-display branch from 6484cf8 to 4f348d0 Compare September 27, 2026 01:39
@TheGreatAxios
TheGreatAxios merged commit 0011950 into main Sep 27, 2026
1 check passed
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.

1 participant