Bulwark Webmail: The Read Receipt Sends Mail With a Foreign Sender
A subject carrying a line break is copied unchanged into the read receipt's headers, which the victim sends themselves
Advisory ID: TP-2026-102
Product: Bulwark Webmail (web interface for the Stalwart mail server, Next.js)
Vulnerability type: Header injection through CRLF (CWE-93)
CVE: requested on 19 September 2026 (GitHub CNA), assignment pending
CVSS 3.1: 5.7 (Medium) · CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N
Affected versions: >= 1.7.3, <= 1.9.2
Vendor advisory: GHSA-w38p-hpqv-g89c
Fixed in: 1.10.0
Reported: 16 September 2026
Summary
Bulwark assembles the read receipt byte by byte itself and inserts the source message's subject into the subject line. The function that encodes header values only acts when the value contains a character outside the ASCII range. Carriage return and line feed sit inside that range, so a subject with an embedded line break is passed through unchanged. The mail server decodes the subject before the client sees it, so a sender smuggles the break past SMTP inside an encoded word. When the victim answers the read-receipt request, the injected lines become real headers and a real body in a message that the victim's own account composes, files and submits.
Root cause
encodeHeaderWord() RFC 2047-encodes a header value only when it contains a character outside ASCII, and otherwise returns it unchanged (lib/mdn.ts:65). Carriage return and line feed are ASCII characters, so a subject that already carries a break passes that check and is interpolated verbatim into the subject line of the assembled message. The Stalwart mail server RFC 2047-decodes the subject before the client receives it, so the break slips past SMTP inside a base64 encoded word and arrives decoded in the subject field. The mail server's query returns the last sender header, and the injected block sits after the genuine one, which is why the sender also chooses the visible sender identity. The read receipt is composed by the victim's account, filed into Sent and submitted through their authenticated session.
Proof of Concept
# subject of the source email, delivered as an encoded word so the
# line break gets past SMTP:
Subject: =?utf-8?B?<base64 of: Hello\r\nFrom: [email protected]\r\n...>?=
# Stalwart decodes the subject and the break reaches the client.
# the victim confirms the read receipt -> the injected lines become real
# headers and a real body in a message composed and sent by the
# victim's own account.
The victim's read-receipt setting must be ask, which is the default, or always; the setting never is immune. The message must also land in a folder other than Junk, Sent, Drafts or Trash, since the banner only appears there.
Impact
- Sending a message with an arbitrary sender, reply address and HTML body out of the victim's mailbox.
- Submission through the victim's authenticated connection, so the message passes every sender-domain check.
- Filing of the forged message into the victim's Sent folder, which makes it look genuine afterwards too.
- Suitability for targeted fraud, since recipients receive a message from a known, legitimate mailbox.
References
Is Something Like This in Your Software?
Our team found this vulnerability in the course of its work. Have your applications tested by the same specialists, with a penetration test from turingpoint.
